From f8f80a07afd45d60c2975bfd7e4b859fb8c10a96 Mon Sep 17 00:00:00 2001 From: Lassi Marttala Date: Wed, 16 May 2012 10:10:12 +0200 Subject: [GDLT-67] dlt-system v2.0, check full commit message for rebase details [GDLT-67] Prepare build system. [GDLT-67] Config parsing, structure for thread handling [GDLT-67] Finalize configuration reading. [GDLT-67] Reimplementation of syslog, logfile, logprocess, shell. [GDLT-67] First complete version of the new dlt-system. [GDLT-67] Fixed header comments. authors, file names. [GDLT-67] Final touches. [GDLT-67] Fixed a problem with thread creation in optimized release binary. [GDLT-67] New configuration file. [GDLT-67] Added dlt debug output Signed-off-by: Christian Muck --- include/dlt/dlt_filetransfer.h | 32 +- src/CMakeLists.txt | 0 src/daemon/dlt.conf | 6 +- src/lib/dlt_filetransfer.c | 34 ++ src/system/CMakeLists.txt | 4 +- src/system/dlt-system-filetransfer.c | 317 ++++++++++++++ src/system/dlt-system-log.c | 495 --------------------- src/system/dlt-system-log.h | 66 --- src/system/dlt-system-logfile.c | 148 +++++++ src/system/dlt-system-options.c | 386 ++++++++++++++++ src/system/dlt-system-process-handling.c | 182 ++++++++ src/system/dlt-system-processes.c | 167 +++++++ src/system/dlt-system-shell.c | 104 +++++ src/system/dlt-system-syslog.c | 153 +++++++ src/system/dlt-system.c | 728 ++----------------------------- src/system/dlt-system.conf | 49 ++- src/system/dlt-system.h | 178 +++++--- src/system/dlt-system_cfg.h | 68 --- 18 files changed, 1691 insertions(+), 1426 deletions(-) mode change 100755 => 100644 src/CMakeLists.txt mode change 100755 => 100644 src/system/CMakeLists.txt create mode 100644 src/system/dlt-system-filetransfer.c delete mode 100644 src/system/dlt-system-log.c delete mode 100644 src/system/dlt-system-log.h create mode 100644 src/system/dlt-system-logfile.c create mode 100644 src/system/dlt-system-options.c create mode 100644 src/system/dlt-system-process-handling.c create mode 100644 src/system/dlt-system-processes.c create mode 100644 src/system/dlt-system-shell.c create mode 100644 src/system/dlt-system-syslog.c mode change 100755 => 100644 src/system/dlt-system.c delete mode 100644 src/system/dlt-system_cfg.h diff --git a/include/dlt/dlt_filetransfer.h b/include/dlt/dlt_filetransfer.h index 077e3f0..44436e7 100644 --- a/include/dlt/dlt_filetransfer.h +++ b/include/dlt/dlt_filetransfer.h @@ -82,16 +82,28 @@ extern int dlt_user_log_file_packagesCount(DltContext *fileContext, const char * extern int dlt_user_log_file_infoAbout(DltContext *fileContext, const char *filename); -//!Transfer the head of the file as a dlt logs. -/**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number, - * the file name, the file size, package number the file have and the buffer size. - * All these informations are needed from the plugin of the dlt viewer. - * See the Mainpages.c for more informations. - * @param fileContext Specific context to log the file to dlt - * @param filename Absolute file path - * @return Returns 0 if everything was okey. If there was a failure value < 0 will be returned. - */ -extern int dlt_user_log_file_header(DltContext *fileContext, const char *filename); + //!Transfer the head of the file as a dlt logs. + /**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number, + * the file name, the file size, package number the file have and the buffer size. + * All these informations are needed from the plugin of the dlt viewer. + * See the Mainpages.c for more informations. + * @param fileContext Specific context to log the file to dlt + * @param filename Absolute file path + * @param alias Alias for the file. An alternative name to show in the receiving end + * @return Returns 0 if everything was okey. If there was a failure value < 0 will be returned. + */ + extern int dlt_user_log_file_header_alias(DltContext *fileContext, const char *filename, const char *alias); + + //!Transfer the head of the file as a dlt logs. + /**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number, + * the file name, the file size, package number the file have and the buffer size. + * All these informations are needed from the plugin of the dlt viewer. + * See the Mainpages.c for more informations. + * @param fileContext Specific context to log the file to dlt + * @param filename Absolute file path + * @return Returns 0 if everything was okey. If there was a failure value < 0 will be returned. + */ + extern int dlt_user_log_file_header(DltContext *fileContext, const char *filename); //!Transfer the content data of a file. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt old mode 100755 new mode 100644 diff --git a/src/daemon/dlt.conf b/src/daemon/dlt.conf index 9883acc..17b30ac 100644 --- a/src/daemon/dlt.conf +++ b/src/daemon/dlt.conf @@ -46,13 +46,13 @@ LoggingFilename = /tmp/dlt.log ######################################################################## # Store DLT messages to local directory, if not set offline Trace is off (Default: off) -# OfflineTraceDirectory = /tmp +OfflineTraceDirectory = /tmp # Maximum size in bytes of one trace file (Default: 1000000) -# OfflineTraceFileSize = 1000000 +OfflineTraceFileSize = 1000000 # Maximum size of all trace files (Default: 4000000) -# OfflineTraceMaxSize = 4000000 +OfflineTraceMaxSize = 4000000 ######################################################################## # Local console output configuration # diff --git a/src/lib/dlt_filetransfer.c b/src/lib/dlt_filetransfer.c index 561d540..d690696 100644 --- a/src/lib/dlt_filetransfer.c +++ b/src/lib/dlt_filetransfer.c @@ -294,6 +294,40 @@ int dlt_user_log_file_packagesCount(DltContext *fileContext, const char *filenam } } +//!Transfer the head of the file as a dlt logs. +/**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number, + * the file name, the file size, package number the file have and the buffer size. + * All these informations are needed from the plugin of the dlt viewer. + * See the Mainpages.c for more informations. + * @param fileContext Specific context to log the file to dlt + * @param filename Absolute file path + * @param alias Alias for the file. An alternative name to show in the receiving end + * @return Returns 0 if everything was okey. If there was a failure a value < 0 will be returned. + */ +int dlt_user_log_file_header_alias(DltContext *fileContext,const char *filename, const char *alias){ + + if(isFile(filename)) + { + DLT_LOG(*fileContext,DLT_LOG_INFO, + DLT_STRING("FLST"), + DLT_UINT(getFileSerialNumber(filename)), + DLT_STRING(alias), + DLT_UINT(getFilesize(filename)), + DLT_STRING(getFileCreationDate2(filename)); + DLT_UINT(dlt_user_log_file_packagesCount(fileContext,filename)), + DLT_UINT(BUFFER_SIZE), + DLT_STRING("FLST") + ); + + return 0; + } + else + { + dlt_user_log_file_errorMessage(fileContext,filename, DLT_FILETRANSFER_ERROR_FILE_HEAD); + return DLT_FILETRANSFER_ERROR_FILE_HEAD; + } +} + //!Transfer the head of the file as a dlt logs. /**The head of the file must be logged to dlt because the head contains inforamtion about the file serial number, * the file name, the file size, package number the file have and the buffer size. diff --git a/src/system/CMakeLists.txt b/src/system/CMakeLists.txt old mode 100755 new mode 100644 index bdd9b8d..be8e1c9 --- a/src/system/CMakeLists.txt +++ b/src/system/CMakeLists.txt @@ -14,7 +14,9 @@ # @licence end@ ######## -set(dlt_system_SRCS dlt-system dlt-system-log) +set(dlt_system_SRCS dlt-system dlt-system-options dlt-system-process-handling + dlt-system-filetransfer dlt-system-logfile dlt-system-processes dlt-system-shell + dlt-system-syslog) add_executable(dlt-system ${dlt_system_SRCS}) target_link_libraries(dlt-system dlt z) set_target_properties(dlt-system PROPERTIES LINKER_LANGUAGE C) diff --git a/src/system/dlt-system-filetransfer.c b/src/system/dlt-system-filetransfer.c new file mode 100644 index 0000000..b05fc39 --- /dev/null +++ b/src/system/dlt-system-filetransfer.c @@ -0,0 +1,317 @@ +/** + * @licence app begin@ + * Copyright (C) 2012 BMW AG + * + * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * + * \author Lassi Marttala BMW 2012 + * + * \file dlt-system-filetransfer.c + * For further information see http://www.genivi.org/. + * @licence end@ + */ + +/******************************************************************************* +** ** +** SRC-MODULE: dlt-system-filetransfer.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Lassi Marttala ** +** Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dlt-system.h" +#include "dlt.h" +#include "dlt_filetransfer.h" + +#define INOTIFY_SZ (sizeof(struct inotify_event)) +#define INOTIFY_LEN (INOTIFY_SZ + 256) +#define Z_CHUNK_SZ 1024*128 + +extern DltSystemThreads threads; +// From dlt_filetransfer +extern unsigned long getFileSerialNumber(const char* file); + +DLT_IMPORT_CONTEXT(dltsystem); +DLT_DECLARE_CONTEXT(filetransferContext) + +typedef struct { + int handle; + int fd[DLT_SYSTEM_LOG_DIRS_MAX]; +} s_ft_inotify; + +s_ft_inotify ino; + +char *unique_name(const char *src) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-filetransfer, creating unique temporary file name.")); + time_t t = time(NULL); + unsigned long l = getFileSerialNumber(src) ^ t; + // Length of ULONG_MAX + 1 + char *ret = malloc(11); + snprintf(ret, 11, "%lu", l); + return ret; +} + +char *compress_file(char *src, int level) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-filetransfer, compressing file.")); + char *buf; + char *dst = malloc(strlen(src)+4); + char dst_mode[8]; + sprintf(dst, "%s.gz", src); + sprintf(dst_mode, "wb%d", level); + + gzFile dst_file; + FILE *src_file; + + dst_file = gzopen(dst, dst_mode); + if(dst_file < 0) + { + free(dst); + return NULL; + } + + src_file = fopen(src, "r"); + + if(src_file < 0) + { + gzclose(dst_file); + free(dst); + return NULL; + } + + buf = malloc(Z_CHUNK_SZ); + + while(!feof(src_file)) + { + int read = fread(buf, 1, Z_CHUNK_SZ, src_file); + if(ferror(src_file)) + { + free(buf); + free(dst); + gzclose(dst_file); + return NULL; + } + gzwrite(dst_file, buf, read); + } + + remove(src); + free(buf); + fclose(src_file); + gzclose(dst_file); + return dst; +} + +int send_one(char *src, FiletransferOptions opts, int which) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-filetransfer, sending a file.")); + sleep(opts.TimeDelay); + + // Prepare all needed file names + char *fn = basename(src); + char *rn = unique_name(src); + char *dst = malloc(strlen(opts.TempDir)+strlen(rn)+2); + sprintf(dst, "%s/%s", opts.TempDir, rn); + rename(src, dst); + + // Compress if needed + if(opts.Compression[which] > 0) + { + dst = compress_file(dst, opts.CompressionLevel[which]); + char *old_fn = fn; + fn = malloc(strlen(old_fn)+4); + sprintf(fn, "%s.gz", old_fn); + } + + if(dlt_user_log_file_header_alias(&filetransferContext, dst, fn) == 0) + { + int pkgcount = dlt_user_log_file_packagesCount(&filetransferContext, dst); + int lastpkg = 0; + while(lastpkg < pkgcount) + { + int total = 2; + int used = 2; + while(total-used < total/2) + { + struct timespec t; + t.tv_sec = 0; + t.tv_nsec = 1000*opts.TimeoutBetweenLogs; + nanosleep(&t, NULL); + dlt_user_check_buffer(&total, &used); + } + lastpkg++; + if(dlt_user_log_file_data(&filetransferContext, dst, lastpkg, opts.TimeoutBetweenLogs) < 0) + break; + } + dlt_user_log_file_end(&filetransferContext, dst, 1); + } + + if(opts.Compression[which] > 0) + free(fn); + free(rn); + free(dst); + return 0; +} + +int flush_dir(FiletransferOptions opts, int which) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-filetransfer, flush directory of old files.")); + const char *sdir = opts.Directory[which]; + char *fn; + struct dirent *dp; + DIR *dir; + + dir = opendir(sdir); + if(dir > 0) + { + while((dp = readdir(dir)) != NULL) + { + if(dp->d_type != DT_REG) + continue; + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-filetransfer, old file found in directory.")); + fn = malloc(strlen(sdir)+dp->d_reclen+2); + sprintf(fn, "%s/%s", sdir, dp->d_name); + if(send_one(fn, opts, which) < 0) + return -1; + } + } + closedir(dir); + return 0; +} + +int init_filetransfer_dirs(FiletransferOptions opts) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-filetransfer, initializing inotify on directories.")); + ino.handle = inotify_init(); + int i; + + if(ino.handle < 0) + { + DLT_LOG(filetransferContext, DLT_LOG_FATAL, + DLT_STRING("Failed to initialize inotify in dlt-system file transfer.")); + return -1; + } + for(i = 0;i < opts.Count;i++) + { + ino.fd[i] = inotify_add_watch(ino.handle, opts.Directory[i], + IN_CLOSE_WRITE|IN_MOVED_TO); + if(ino.fd[i] < 0) + { + char buf[1024]; + snprintf(buf, 1024, "Failed to add inotify watch to directory %s in dlt-system file transfer.", + opts.Directory[i]); + DLT_LOG(filetransferContext, DLT_LOG_FATAL, + DLT_STRING(buf)); + return -1; + } + flush_dir(opts, i); + } + return 0; +} + +int wait_for_files(FiletransferOptions opts) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, waiting for files.")); + char buf[INOTIFY_LEN]; + int len = read(ino.handle, buf, INOTIFY_LEN); + if(len < 0) + { + DLT_LOG(filetransferContext, DLT_LOG_ERROR, + DLT_STRING("Error while waiting for files in dlt-system file transfer.")); + return -1; + } + + int i = 0; + while(ilen > 0) + { + if(ie->mask & IN_CLOSE_WRITE || ie->mask & IN_MOVED_TO) + { + int j; + for(j = 0;j < opts.Count;j++) + { + if(ie->wd == ino.fd[j]) + { + DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, found new file.")); + char *tosend = malloc(strlen(opts.Directory[j])+ie->len+1); + sprintf(tosend, "%s/%s", opts.Directory[j], ie->name); + send_one(tosend, opts, j); + free(tosend); + } + } + } + } + i += INOTIFY_SZ + ie->len; + } + return 0; +} + +void filetransfer_thread(void *v_conf) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, in thread.")); + DltSystemConfiguration *conf = (DltSystemConfiguration *) v_conf; + DLT_REGISTER_CONTEXT(filetransferContext, conf->Filetransfer.ContextId, + "File transfer manager."); + + sleep(conf->Filetransfer.TimeStartup); + + if(init_filetransfer_dirs(conf->Filetransfer) < 0) + return; + + while(!threads.shutdown) + { + if(wait_for_files(conf->Filetransfer) < 0) + return; + sleep(conf->Filetransfer.TimeDelay); + } +} + +void start_filetransfer(DltSystemConfiguration *conf) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system-filetransfer, start.")); + static pthread_attr_t t_attr; + static pthread_t pt; + pthread_create(&pt, &t_attr, (void *)filetransfer_thread, conf); + threads.threads[threads.count++] = pt; +} diff --git a/src/system/dlt-system-log.c b/src/system/dlt-system-log.c deleted file mode 100644 index c4a3b7e..0000000 --- a/src/system/dlt-system-log.c +++ /dev/null @@ -1,495 +0,0 @@ -/** - * @licence app begin@ - * Copyright (C) 2012 BMW AG - * - * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. - * - * Contributions are licensed to the GENIVI Alliance under one or more - * Contribution License Agreements. - * - * \copyright - * This Source Code Form is subject to the terms of the - * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with - * this file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * - * \author Alexander Wenzel BMW 2011-2012 - * - * \file dlt-system-log.c - * For further information see http://www.genivi.org/. - * @licence end@ - */ - -/******************************************************************************* -** ** -** SRC-MODULE: dlt-system-log.c ** -** ** -** TARGET : linux ** -** ** -** PROJECT : DLT ** -** ** -** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** -** ** -** PURPOSE : ** -** ** -** REMARKS : ** -** ** -** PLATFORM DEPENDANT [yes/no]: yes ** -** ** -** TO BE CHANGED BY USER [yes/no]: no ** -** ** -*******************************************************************************/ - -/******************************************************************************* -** Author Identity ** -******************************************************************************** -** ** -** Initials Name Company ** -** -------- ------------------------- ---------------------------------- ** -** aw Alexander Wenzel BMW ** -*******************************************************************************/ - -/******************************************************************************* -** Revision Control History ** -*******************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dlt_common.h" -#include "dlt_user.h" -#include "dlt_filetransfer.h" - -#include "dlt-system.h" -#include "dlt-system_cfg.h" -#include "dlt-system-log.h" - -/* Size of the compression buffer */ -#define Z_CHUNK_SZ 1024*128 - -/* Check if the file name ends in .z */ -int dlt_system_is_gz_file(char *file_name) -{ - size_t f_len = strlen(file_name); - size_t z_len = strlen(".gz"); - - if(z_len > f_len) - return 0; - - if(strncmp( file_name + f_len - z_len, ".gz", z_len ) == 0) - { - return 1; - } - return 0; -} -/* File compression routine. - * Side effects: - * - modifies src to point to the compressed file. - * - removes the original file - */ -int dlt_system_compress_file(char *src_name, int level) -{ - char dst_name[256]; - char dst_mode[8]; - char *buf; - - gzFile dst_file; - FILE *src_file; - - /* Initialize output */ - sprintf(dst_name, "%s.gz", src_name); - sprintf(dst_mode, "wb%d", level); - dst_file = gzopen(dst_name, dst_mode); - - if(!dst_file) - { - return -1; - } - /* Initialize input */ - src_file = fopen(src_name, "r"); - - if(!src_file) - { - gzclose(dst_file); - return -1; - } - - /* Initialize buffer */ - buf = malloc(Z_CHUNK_SZ); - - /* Read from the src and write to dst */ - while(!feof(src_file)) - { - int read = fread(buf, 1, Z_CHUNK_SZ, src_file); - if(ferror(src_file)) - { - free(buf); - gzclose(dst_file); - fclose(src_file); - return -1; - } - gzwrite(dst_file, buf, read); - } - - /* Clean up */ - free(buf); - gzclose(dst_file); - fclose(src_file); - - /* Remove source file */ - remove(src_name); - - /* Rename in name buffer */ - strcpy(src_name, dst_name); - - return 0; -} - -int dlt_system_inotify_handle; -int dlt_system_watch_descriptor_dir1; -int dlt_system_watch_descriptor_dir2; -#define INOTIFY_SZ (sizeof(struct inotify_event)) -#define INOTIFY_LEN (INOTIFY_SZ + 256) -#define MAX_FILE_QUEUE 256 - -int dlt_system_filetransfer_init(DltSystemOptions *options,DltSystemRuntime *runtime) -{ - runtime->filetransferFile[0] = 0; - runtime->filetransferRunning = 0; - runtime->filetransferCountPackages = 0; - - // Initialize watch for filetransfer directories. - dlt_system_inotify_handle = inotify_init1(IN_NONBLOCK); - if(dlt_system_inotify_handle < 0) - { - return -1; - } - - dlt_system_watch_descriptor_dir1 = inotify_add_watch(dlt_system_inotify_handle, options->FiletransferDirectory1, IN_CLOSE_WRITE|IN_MOVED_TO); - dlt_system_watch_descriptor_dir2 = inotify_add_watch(dlt_system_inotify_handle, options->FiletransferDirectory2, IN_CLOSE_WRITE|IN_MOVED_TO); - if(dlt_system_watch_descriptor_dir1 < 0 || dlt_system_watch_descriptor_dir2 < 0) - { - return -1; - } - return 0; -} - -void dlt_system_filetransfer_run(DltSystemOptions *options,DltSystemRuntime *runtime,DltContext *context) -{ - struct stat status; - int transferResult; - int total_size, used_size; - static char inotify_buf[INOTIFY_LEN]; - static char *file_stack1[MAX_FILE_QUEUE]; - static char *file_stack2[MAX_FILE_QUEUE]; - static int file_stack_ptr1 = -1; - static int file_stack_ptr2 = -1; - static int first_run = 1; - - if(runtime->filetransferRunning == 0) { - /* delete last transmitted file */ - if(runtime->filetransferFile[0]!=0) { - if(stat(runtime->filetransferFile,&status)==0) - { - if(runtime->filetransferFilesize == status.st_size) - { - /* delete file only if size is not changed since starting transfer */ - printf("Remove File: %s\n",runtime->filetransferFile); - if(remove(runtime->filetransferFile)) { - printf("Remove file %s failed!\n",runtime->filetransferFile); - } - } - } - runtime->filetransferFile[0]=0; - } - - /* Check inotify watch, add new files to stack */ - if(file_stack_ptr1 < (MAX_FILE_QUEUE/2) - 4 && file_stack_ptr2 < (MAX_FILE_QUEUE/2) - 4) - { - int len = read(dlt_system_inotify_handle, inotify_buf, INOTIFY_LEN); - if(len < 0) - { - if(errno != EWOULDBLOCK) - { - fprintf(stderr, "dlt_system_filetransfer_run error reading inotify handle. %d\n", errno); - return; - } - } - int i = 0; - while(i < len) - { - struct inotify_event *ievent = (struct inotify_event *)&inotify_buf[i]; - if(ievent->len > 0) - { - if((ievent->mask & IN_CLOSE_WRITE || ievent->mask & IN_MOVED_TO) && - !dlt_system_is_gz_file(ievent->name)) - { - if(ievent->wd == dlt_system_watch_descriptor_dir1) - { - int plen = strlen(options->FiletransferDirectory1); - plen += ievent->len + 1; - file_stack_ptr1++; - file_stack1[file_stack_ptr1] = malloc(plen); - sprintf(file_stack1[file_stack_ptr1], "%s/%s", - options->FiletransferDirectory1, - ievent->name); - } - else if(ievent->wd == dlt_system_watch_descriptor_dir2) - { - int plen = strlen(options->FiletransferDirectory2); - plen += ievent->len + 1; - file_stack_ptr2++; - file_stack2[file_stack_ptr2] = malloc(plen); - sprintf(file_stack2[file_stack_ptr2], "%s/%s", - options->FiletransferDirectory2, - ievent->name); - } - else - { - fprintf(stderr, "Unknown inotify descriptor in dlt_system_filetransfer_run.\n"); - return; - } - } - } - i += INOTIFY_SZ + ievent->len; - } - } - - // Check if there were files before inotify was registered. - // TODO: This is awfully clumsy, review when modularizing - if(first_run && (file_stack_ptr1 < (MAX_FILE_QUEUE/2) - 4 && file_stack_ptr2 < (MAX_FILE_QUEUE/2) - 4)) - { - char filename[256]; - struct dirent *dp; - DIR *dir; - filename[0] = 0; - dir = opendir(options->FiletransferDirectory1); - if(dir > 0) { - while ((dp=readdir(dir)) != NULL) { - if(strcmp(dp->d_name,".")!=0 && strcmp(dp->d_name,"..")!=0) { - sprintf(filename,"%s/%s",options->FiletransferDirectory1,dp->d_name); - if(stat(filename,&status)==0) - { - int plen = strlen(filename)+1; - file_stack_ptr1++; - file_stack1[file_stack_ptr1] = malloc(plen); - strcpy(file_stack1[file_stack_ptr1], filename); - } - } - } - closedir(dir); - } - dir = opendir(options->FiletransferDirectory2); - if(dir > 0) { - while ((dp=readdir(dir)) != NULL) { - if(strcmp(dp->d_name,".")!=0 && strcmp(dp->d_name,"..")!=0) { - sprintf(filename,"%s/%s",options->FiletransferDirectory2,dp->d_name); - if(stat(filename,&status)==0) - { - int plen = strlen(filename)+1; - file_stack_ptr2++; - file_stack2[file_stack_ptr2] = malloc(plen); - strcpy(file_stack2[file_stack_ptr2], filename); - } - } - } - closedir(dir); - } - first_run = 0; - } - - /* Select file to transfer */ - if(file_stack_ptr1 > -1) - { - memset(runtime->filetransferFile, 0, 256); - /* - * FIXME: filetransferfile is constant 256 len buffer - * file_stack items are dynamically allocated. This - * might overflow, (and will, eventually...) - */ - memcpy(runtime->filetransferFile, file_stack1[file_stack_ptr1], strlen(file_stack1[file_stack_ptr1])); - free(file_stack1[file_stack_ptr1--]); - if(options->FiletransferCompression1) - { - dlt_system_compress_file(runtime->filetransferFile, options->FiletransferCompressionLevel); - } - struct stat st; - stat(runtime->filetransferFile, &st); - runtime->filetransferFilesize = st.st_size; - } - else if(file_stack_ptr2 > -1) - { - memset(runtime->filetransferFile, 0, 256); - memcpy(runtime->filetransferFile, file_stack2[file_stack_ptr2], strlen(file_stack2[file_stack_ptr2])); - free(file_stack2[file_stack_ptr2--]); - if(options->FiletransferCompression2) - { - dlt_system_compress_file(runtime->filetransferFile, options->FiletransferCompressionLevel); - } - struct stat st; - stat(runtime->filetransferFile, &st); - runtime->filetransferFilesize = st.st_size; - } - - /* start filetransfer if file exists */ - if(runtime->filetransferFile[0]) { - printf("Start Filetransfer: %s\n",runtime->filetransferFile); - runtime->filetransferCountPackages = dlt_user_log_file_packagesCount(context,runtime->filetransferFile); - if(runtime->filetransferCountPackages < 0 ) - { - /* a problem occured; stop filetransfer and continue with next file after timeout */ - printf("Error: dlt_user_log_file_packagesCount\n"); - runtime->filetransferCountPackages = 0; - runtime->filetransferRunning = 0; - runtime->timeFiletransferDelay = options->FiletransferTimeDelay; - return; - } - runtime->filetransferRunning = 1; - transferResult = dlt_user_log_file_header(context,runtime->filetransferFile); - if(transferResult < 0) - { - /* a problem occured; stop filetransfer and continue with next file after timeout */ - printf("Error: dlt_user_log_file_header\n"); - runtime->filetransferCountPackages = 0; - runtime->filetransferRunning = 0; - runtime->timeFiletransferDelay = options->FiletransferTimeDelay; - - return; - } - runtime->filetransferLastSentPackage = 0; - } - - } - - if (runtime->filetransferRunning == 1) { - int iteration_package_count = 0; - /* filetransfer is running, send next data */ - while(runtime->filetransferLastSentPackagefiletransferCountPackages) { - /* wait sending next package if more than 50% of buffer used */ - dlt_user_check_buffer(&total_size, &used_size); - if((total_size - used_size) < (total_size/2)) - { - break; - } - - /* Give a chance for other packets to go through periodically */ - if(iteration_package_count > 100) - { - iteration_package_count = 0; - break; - } - - runtime->filetransferLastSentPackage++; - transferResult = dlt_user_log_file_data(context,runtime->filetransferFile,runtime->filetransferLastSentPackage,options->FiletransferTimeoutBetweenLogs); - if(transferResult < 0) - { - /* a problem occured; stop filetransfer and continue with next file after timeout */ - printf("Error: dlt_user_log_file_data\n"); - runtime->filetransferCountPackages = 0; - runtime->filetransferRunning = 0; - runtime->timeFiletransferDelay = options->FiletransferTimeDelay; - return; - } - iteration_package_count++; - } - if(runtime->filetransferLastSentPackage==runtime->filetransferCountPackages) { - transferResult = dlt_user_log_file_end(context,runtime->filetransferFile,0); - if(transferResult < 0) - { - printf("Error: dlt_user_log_file_end\n"); - runtime->filetransferCountPackages = 0; - runtime->filetransferRunning = 0; - runtime->timeFiletransferDelay = options->FiletransferTimeDelay; - return; - } - runtime->timeFiletransferDelay = options->FiletransferTimeDelay; - runtime->filetransferRunning = 0; - } - } -} - -void dlt_system_log_file(DltSystemOptions *options,DltContext *context,int num) { - FILE * pFile; - char buffer[1024]; - int bytes; - int seq = 1; - - pFile = fopen(options->LogFileFilename[num],"r"); - - if(pFile>0) - { - while (!feof(pFile)) { - bytes = fread(buffer,1,sizeof(buffer)-1,pFile); - if(bytes>=0) - buffer[bytes] = 0; - else - buffer[0] = 0; - - if(feof(pFile)) { - DLT_LOG(*context, DLT_LOG_INFO, DLT_INT(seq*-1), DLT_STRING(buffer)); - } - else { - DLT_LOG(*context, DLT_LOG_INFO, DLT_INT(seq++), DLT_STRING(buffer)); - } - } - fclose(pFile); - } -} - -void dlt_system_log_process(DltSystemOptions *options,DltContext *context,int num) { - FILE * pFile; - struct dirent *dp; - char filename[256]; - char buffer[1024]; - int bytes; - int found = 0; - - /* go through all dlt files in directory */ - DIR *dir = opendir("/proc"); - if(dir>0) { - while ((dp=readdir(dir)) != NULL) { - if(dp->d_name[0]>'0' && dp->d_name[0]<'9') { - buffer[0] = 0; - sprintf(filename,"/proc/%s/cmdline",dp->d_name); - pFile = fopen(filename,"r"); - if(pFile>0) - { - bytes = fread(buffer,1,sizeof(buffer)-1,pFile); - fclose(pFile); - } - if((strcmp(options->LogProcessName[num],"*")==0) || - (strcmp(buffer,options->LogProcessName[num])==0) ) { - found = 1; - sprintf(filename,"/proc/%s/%s",dp->d_name,options->LogProcessFilename[num]); - pFile = fopen(filename,"r"); - if(pFile>0) - { - bytes = fread(buffer,1,sizeof(buffer)-1,pFile); - fclose(pFile); - - if(bytes>0) { - buffer[bytes] = 0; - DLT_LOG(*context, DLT_LOG_INFO, DLT_INT(atoi(dp->d_name)),DLT_STRING(options->LogProcessFilename[num]), DLT_STRING(buffer)); - } - } - if(strcmp(options->LogProcessName[num],"*")!=0) - break; - } - } - } - closedir(dir); - } - - if(!found) { - DLT_LOG(*context, DLT_LOG_INFO, DLT_STRING("Process"), DLT_STRING(options->LogProcessName[num]),DLT_STRING("not running!")); - } -} diff --git a/src/system/dlt-system-log.h b/src/system/dlt-system-log.h deleted file mode 100644 index a9940ba..0000000 --- a/src/system/dlt-system-log.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @licence app begin@ - * Copyright (C) 2012 BMW AG - * - * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. - * - * Contributions are licensed to the GENIVI Alliance under one or more - * Contribution License Agreements. - * - * \copyright - * This Source Code Form is subject to the terms of the - * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with - * this file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * - * \author Alexander Wenzel BMW 2011-2012 - * - * \file dlt-system-log.h - * For further information see http://www.genivi.org/. - * @licence end@ - */ - - -/******************************************************************************* -** ** -** SRC-MODULE: dlt-system-log.h ** -** ** -** TARGET : linux ** -** ** -** PROJECT : DLT ** -** ** -** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** -** ** -** PURPOSE : ** -** ** -** REMARKS : ** -** ** -** PLATFORM DEPENDANT [yes/no]: yes ** -** ** -** TO BE CHANGED BY USER [yes/no]: no ** -** ** -*******************************************************************************/ - -/******************************************************************************* -** Author Identity ** -******************************************************************************** -** ** -** Initials Name Company ** -** -------- ------------------------- ---------------------------------- ** -** aw Alexander Wenzel BMW ** -*******************************************************************************/ - -/******************************************************************************* -** Revision Control History ** -*******************************************************************************/ - -#ifndef DLT_SYSTEM_LOG_H -#define DLT_SYSTEM_LOG_H - -extern int dlt_system_filetransfer_init(DltSystemOptions *options,DltSystemRuntime *runtime); -extern void dlt_system_filetransfer_run(DltSystemOptions *options,DltSystemRuntime *runtime,DltContext *context); - -extern void dlt_system_log_file(DltSystemOptions *options,DltContext *context,int num); -extern void dlt_system_log_process(DltSystemOptions *options,DltContext *context,int num); - -#endif /* DLT_SYSTEM_LOG_H */ diff --git a/src/system/dlt-system-logfile.c b/src/system/dlt-system-logfile.c new file mode 100644 index 0000000..8872d20 --- /dev/null +++ b/src/system/dlt-system-logfile.c @@ -0,0 +1,148 @@ +/** + * @licence app begin@ + * Copyright (C) 2012 BMW AG + * + * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * + * \author Lassi Marttala BMW 2012 + * + * \file dlt-system-logfile.c + * For further information see http://www.genivi.org/. + * @licence end@ + */ + +/******************************************************************************* +** ** +** SRC-MODULE: dlt-system-logfile.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Lassi Marttala ** +** Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + + +#include +#include +#include "dlt-system.h" + +// Modes of sending +#define SEND_MODE_OFF 0 +#define SEND_MODE_ONCE 1 +#define SEND_MODE_ON 2 + +DLT_IMPORT_CONTEXT(dltsystem); + +extern DltSystemThreads threads; +DltContext logfileContext[DLT_SYSTEM_LOG_FILE_MAX]; + +void send_file(LogFileOptions fileopt, int n) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-logfile, sending file.")); + FILE * pFile; + DltContext context = logfileContext[n]; + char buffer[1024]; + int bytes; + int seq = 1; + + pFile = fopen(fileopt.Filename[n],"r"); + + if(pFile>0) + { + while (!feof(pFile)) { + bytes = fread(buffer,1,sizeof(buffer)-1,pFile); + if(bytes>=0) + buffer[bytes] = 0; + else + buffer[0] = 0; + + if(feof(pFile)) { + DLT_LOG(context, DLT_LOG_INFO, DLT_INT(seq*-1), DLT_STRING(buffer)); + } + else { + DLT_LOG(context, DLT_LOG_INFO, DLT_INT(seq++), DLT_STRING(buffer)); + } + } + fclose(pFile); + } +} + +void register_contexts(LogFileOptions fileopts) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-logfile, registering file contexts.")); + int i; + for(i = 0;i < fileopts.Count;i++) + { + DLT_REGISTER_CONTEXT(logfileContext[i], fileopts.ContextId[i], + fileopts.Filename[i]); + } +} + +void logfile_thread(void *v_conf) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-logfile, in thread.")); + DltSystemConfiguration *conf = (DltSystemConfiguration *) v_conf; + + register_contexts(conf->LogFile); + + int logfile_delays[DLT_SYSTEM_LOG_FILE_MAX]; + int i; + for(i = 0;i < conf->LogFile.Count;i++) + logfile_delays[i] = conf->LogFile.TimeDelay[i]; + + while(!threads.shutdown) + { + sleep(1); + for(i = 0;i < conf->LogFile.Count;i++) + { + if(conf->LogFile.Mode[i] == SEND_MODE_OFF) + continue; + + if(logfile_delays[i] <= 0) + { + send_file(conf->LogFile, i); + logfile_delays[i] = conf->LogFile.TimeDelay[i]; + if(conf->LogFile.Mode[i] == SEND_MODE_ONCE) + conf->LogFile.Mode[i] = SEND_MODE_OFF; + } + else + { + logfile_delays[i]--; + } + } + } +} + +void start_logfile(DltSystemConfiguration *conf) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-logfile, starting.")); + DLT_LOG(dltsystem,DLT_LOG_DEBUG,DLT_STRING("Starting thread for logfile")); + static pthread_attr_t t_attr; + static pthread_t pt; + pthread_create(&pt, &t_attr, (void *)logfile_thread, conf); + threads.threads[threads.count++] = pt; +} diff --git a/src/system/dlt-system-options.c b/src/system/dlt-system-options.c new file mode 100644 index 0000000..67ae2d4 --- /dev/null +++ b/src/system/dlt-system-options.c @@ -0,0 +1,386 @@ +/** + * @licence app begin@ + * Copyright (C) 2012 BMW AG + * + * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * + * \author Lassi Marttala BMW 2012 + * + * \file dlt-system-options.c + * For further information see http://www.genivi.org/. + * @licence end@ + */ + +/******************************************************************************* +** ** +** SRC-MODULE: dlt-system-options.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Lassi Marttala ** +** Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** lm Lassi Marttala BMW ** +** aw Alexander Wenzel BMW ** +*******************************************************************************/ + +#include "dlt-system.h" + +#include +#include + +/** + * Print information how to use this program. + */ +void usage(char *prog_name) +{ + char version[255]; + dlt_get_version(version); + + printf("Usage: %s [options]\n", prog_name); + printf("Application to transfer system information, logs and files.\n"); + printf("%s\n", version); + printf("Options:\n"); + printf(" -d Daemonize. Detach from terminal and run in background.\n"); + printf(" -c filename Use configuration file. \n"); + printf(" Default: %s\n", DEFAULT_CONF_FILE); + printf(" -h This help message.\n"); +} + +/** + * Initialize command line options with default values. + */ +void init_cli_options(DltSystemCliOptions *options) +{ + options->ConfigurationFileName = DEFAULT_CONF_FILE; + options->Daemonize = 0; +} + +/** + * Read command line options and set the values in provided structure + */ +int read_command_line(DltSystemCliOptions *options, int argc, char *argv[]) +{ + init_cli_options(options); + int opt; + + while((opt = getopt(argc, argv, "c:hd")) != -1) + { + switch(opt) { + case 'd': + { + options->Daemonize = 1; + break; + } + case 'c': + { + options->ConfigurationFileName = malloc(strlen(optarg)+1); + strcpy(options->ConfigurationFileName, optarg); + break; + } + case 'h': + { + usage(argv[0]); + exit(0); + } + default: + { + fprintf(stderr, "Unknown option '%c'\n", optopt); + usage(argv[0]); + return -1; + } + } + } + return 0; +} + +/** + * Initialize configuration to default values. + */ +void init_configuration(DltSystemConfiguration *config) +{ + int i = 0; + + // Common + config->ApplicationId = "SYS"; + + // Syslog + config->Syslog.Enable = 0; + config->Syslog.ContextId = "SYSL"; + config->Syslog.Port = 47111; + + // File transfer + config->Filetransfer.Enable = 0; + config->Filetransfer.ContextId = "FILE"; + config->Filetransfer.TimeDelay = 10; + config->Filetransfer.TimeStartup = 30; + config->Filetransfer.TimeoutBetweenLogs = 10; + config->Filetransfer.Count = 0; + for(i = 0;i < DLT_SYSTEM_LOG_DIRS_MAX;i++) + { + config->Filetransfer.Directory[i] = NULL; + config->Filetransfer.Compression[i] = 0; + config->Filetransfer.CompressionLevel[i] = 5; + } + + // Log file + config->LogFile.Enable = 0; + config->LogFile.Count = 0; + for(i = 0;i < DLT_SYSTEM_LOG_FILE_MAX;i++) + { + config->LogFile.ContextId[i] = NULL; + config->LogFile.Filename[i] = NULL; + config->LogFile.Mode[i] = 0; + config->LogFile.TimeDelay[i] = 0; + } + + // Log process + config->LogProcesses.Enable = 0; + config->LogProcesses.ContextId = "PROC"; + config->LogProcesses.Count = 0; + for(i = 0;i < DLT_SYSTEM_LOG_PROCESSES_MAX;i++) + { + config->LogProcesses.Name[i] = NULL; + config->LogProcesses.Filename[i] = NULL; + config->LogProcesses.Mode[i] = 0; + config->LogProcesses.TimeDelay[i] = 0; + } +} + +/** + * Read options from the configuration file + */ +int read_configuration_file(DltSystemConfiguration *config, char *file_name) +{ + FILE *file; + char *line, *token, *value, *pch; + int ret = 0; + + init_configuration(config); + + file = fopen(file_name, "r"); + + if(file == NULL) + { + fprintf(stderr, "dlt-system-options, could not open configuration file.\n"); + return -1; + } + + line = malloc(MAX_LINE); + token = malloc(MAX_LINE); + value = malloc(MAX_LINE); + + while(fgets(line, MAX_LINE, file) != NULL) + { + token[0] = 0; + value[0] = 0; + + pch = strtok (line, " =\r\n"); + while(pch != NULL) + { + if(pch[0] == '#') + break; + + if(token[0] == 0) + { + strncpy(token, pch, MAX_LINE); + } + else + { + strncpy(value, pch, MAX_LINE); + break; + } + + pch = strtok (NULL, " =\r\n"); + } + + if(token[0] && value[0]) + { + // Common + if(strcmp(token, "ApplicationId") == 0) + { + config->ApplicationId = malloc(strlen(value)+1); + strcpy(config->ApplicationId, value); + } + + // Syslog + else if(strcmp(token, "SyslogEnable") == 0) + { + config->Syslog.Enable = atoi(value); + } + else if(strcmp(token, "SyslogContextId") == 0) + { + config->Syslog.ContextId = malloc(strlen(value)+1); + strcpy(config->Syslog.ContextId, value); + } + else if(strcmp(token, "SyslogPort") == 0) + { + config->Syslog.Port = atoi(value); + } + + // File transfer + else if(strcmp(token, "FiletransferEnable") == 0) + { + config->Filetransfer.Enable = atoi(value); + } + else if(strcmp(token, "FiletransferContextId") == 0) + { + config->Filetransfer.ContextId = malloc(strlen(value)+1); + strcpy(config->Filetransfer.ContextId, value); + } + else if(strcmp(token, "FiletransferTimeStartup") == 0) + { + config->Filetransfer.TimeStartup = atoi(value); + } + else if(strcmp(token, "FiletransferTimeDelay") == 0) + { + config->Filetransfer.TimeDelay = atoi(value); + } + else if(strcmp(token, "FiletransferTimeoutBetweenLogs") == 0) + { + config->Filetransfer.TimeoutBetweenLogs = atoi(value); + } + else if(strcmp(token, "FiletransferTempDir") == 0) + { + config->Filetransfer.TempDir = malloc(strlen(value)+1); + strcpy(config->Filetransfer.TempDir, value); + } + else if(strcmp(token, "FiletransferDirectory") == 0) + { + config->Filetransfer.Directory[config->Filetransfer.Count] = malloc(strlen(value)+1); + strcpy(config->Filetransfer.Directory[config->Filetransfer.Count], value); + } + else if(strcmp(token, "FiletransferCompression") == 0) + { + config->Filetransfer.Compression[config->Filetransfer.Count] = atoi(value); + } + else if(strcmp(token, "FiletransferCompressionLevel") == 0) + { + config->Filetransfer.CompressionLevel[config->Filetransfer.Count] = atoi(value); + if(config->Filetransfer.Count < (DLT_SYSTEM_LOG_DIRS_MAX - 1)) + { + config->Filetransfer.Count++; + } + else + { + fprintf(stderr, + "Too many file transfer directories configured. Maximum: %d\n", + DLT_SYSTEM_LOG_DIRS_MAX); + ret = -1; + break; + } + } + + // Log files + else if(strcmp(token, "LogFileEnable") == 0) + { + config->LogFile.Enable = atoi(value); + } + else if(strcmp(token, "LogFileFilename") == 0) + { + config->LogFile.Filename[config->LogFile.Count] = malloc(strlen(value)+1); + strcpy(config->LogFile.Filename[config->LogFile.Count], value); + } + else if(strcmp(token, "LogFileMode") == 0) + { + config->LogFile.Mode[config->LogFile.Count] = atoi(value); + } + else if(strcmp(token, "LogFileTimeDelay") == 0) + { + config->LogFile.TimeDelay[config->LogFile.Count] = atoi(value); + } + else if(strcmp(token, "LogFileContextId") == 0) + { + config->LogFile.ContextId[config->LogFile.Count] = malloc(strlen(value)+1); + strcpy(config->LogFile.ContextId[config->LogFile.Count], value); + if(config->LogFile.Count < (DLT_SYSTEM_LOG_FILE_MAX - 1)) + { + config->LogFile.Count++; + } + else + { + fprintf(stderr, + "Too many log files configured. Maximum: %d\n", + DLT_SYSTEM_LOG_FILE_MAX); + ret = -1; + break; + } + + } + + // Log Processes + else if(strcmp(token, "LogProcessesEnable") == 0) + { + config->LogProcesses.Enable = atoi(value); + } + else if(strcmp(token, "LogProcessesContextId") == 0) + { + config->LogProcesses.ContextId = malloc(strlen(value)+1); + strcpy(config->LogProcesses.ContextId, value); + } + else if(strcmp(token, "LogProcessName") == 0) + { + config->LogProcesses.Name[config->LogProcesses.Count] = malloc(strlen(value)+1); + strcpy(config->LogProcesses.Name[config->LogProcesses.Count], value); + } + else if(strcmp(token, "LogProcessFilename") == 0) + { + config->LogProcesses.Filename[config->LogProcesses.Count] = malloc(strlen(value)+1); + strcpy(config->LogProcesses.Filename[config->LogProcesses.Count], value); + } + else if(strcmp(token, "LogProcessMode") == 0) + { + config->LogProcesses.Mode[config->LogProcesses.Count] = atoi(value); + } + else if(strcmp(token, "LogProcessTimeDelay") == 0) + { + config->LogProcesses.TimeDelay[config->LogProcesses.Count] = atoi(value); + if(config->LogProcesses.Count < (DLT_SYSTEM_LOG_PROCESSES_MAX - 1)) + { + config->LogProcesses.Count++; + } + else + { + fprintf(stderr, + "Too many processes to log configured. Maximum: %d\n", + DLT_SYSTEM_LOG_PROCESSES_MAX); + ret = -1; + break; + } + + } + } + } + fclose(file); + free(value); + free(token); + free(line); + return ret; +} diff --git a/src/system/dlt-system-process-handling.c b/src/system/dlt-system-process-handling.c new file mode 100644 index 0000000..30568f1 --- /dev/null +++ b/src/system/dlt-system-process-handling.c @@ -0,0 +1,182 @@ +/** + * @licence app begin@ + * Copyright (C) 2012 BMW AG + * + * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * + * \author Lassi Marttala BMW 2012 + * + * \file dlt-system-process-handling.c + * For further information see http://www.genivi.org/. + * @licence end@ + */ + +/******************************************************************************* +** ** +** SRC-MODULE: dlt-systemprocess-handling.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Lassi Marttala ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ +#include "dlt.h" + +#include "dlt-system.h" + +#include +#include +#include +#include +#include +#include +#include + +volatile DltSystemThreads threads; + +DLT_IMPORT_CONTEXT(dltsystem); + +int daemonize() +{ + DLT_LOG(dltsystem,DLT_LOG_DEBUG, + DLT_STRING("dlt-system-process-handling, daemonize")); + + // Fork new process + int f = fork(); + + if(f < 0) + return f; + if(f > 0) + exit(0); + + // Create a new process group + if(setsid < 0) + return -1; + + /** + * Close all file descriptors and point + * stdin, stdout and stderr to /dev/null + */ + int i; + for(i = getdtablesize(); i >= 0; i--) + close(i); + + int fd = i=open("/dev/null",O_RDWR); + + if(fd < 0 || dup(i) < 0 || dup(i) < 0) + return -1; + + /** + * Ignore signals related to child processes and + * terminal handling. + */ + signal(SIGCHLD, SIG_IGN); + signal(SIGTSTP, SIG_IGN); + signal(SIGTTOU, SIG_IGN); + signal(SIGTTIN, SIG_IGN); + return 0; +} + +void start_threads(DltSystemConfiguration *config) +{ + DLT_LOG(dltsystem,DLT_LOG_DEBUG, + DLT_STRING("dlt-system-process-handling, start threads")); + + int i; + threads.count = 0; + threads.shutdown = 0; + for(i = 0;i < MAX_THREADS; i++) + { + threads.threads[i] = 0; + } + + init_shell(); + + if(config->LogFile.Enable) + start_logfile(config); + + if(config->Filetransfer.Enable) + start_filetransfer(config); + + if(config->LogProcesses.Enable) + start_logprocess(config); + + if(config->Syslog.Enable) + start_syslog(config); +} + +/** + * Wait for threads to exit. + * There's not actually a condition currently + * to bail out of file transfer without a signal. + */ +void join_threads() +{ + int i; + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-process-handling, waiting for threads to exit.")); + + if(threads.count < 1) + { + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-process-handling, no threads, waiting for signal.")); + sleep(UINT_MAX); + } + else + { + DLT_LOG(dltsystem,DLT_LOG_DEBUG, + DLT_STRING("dlt-system-process-handling, thread count: "), + DLT_INT(threads.count)); + + for (i = 0; i < threads.count; i++) + { + pthread_join(threads.threads[i], NULL); + DLT_LOG(dltsystem,DLT_LOG_DEBUG, + DLT_STRING("dlt-system-process-handling, thread exit: "), + DLT_INT(threads.threads[i])); + } + } +} + +void dlt_system_signal_handler(int sig) +{ + DLT_LOG(dltsystem,DLT_LOG_DEBUG, + DLT_STRING("dlt-system-process-handling, signal handler")); + + switch (sig) + { + case SIGHUP: + case SIGTERM: + case SIGINT: + case SIGQUIT: + DLT_LOG(dltsystem,DLT_LOG_DEBUG, + DLT_STRING("dlt-system-process-handling, exit, signal: "), + DLT_INT(sig)); + exit(0); + break; + default: + DLT_LOG(dltsystem,DLT_LOG_WARN, + DLT_STRING("dlt-system-process-handling, unknown signal!")); + break; + } +} + diff --git a/src/system/dlt-system-processes.c b/src/system/dlt-system-processes.c new file mode 100644 index 0000000..fd475b8 --- /dev/null +++ b/src/system/dlt-system-processes.c @@ -0,0 +1,167 @@ +/** + * @licence app begin@ + * Copyright (C) 2012 BMW AG + * + * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * + * \author Lassi Marttala BMW 2012 + * + * \file dlt-system-logfile.c + * For further information see http://www.genivi.org/. + * @licence end@ + */ + +/******************************************************************************* +** ** +** SRC-MODULE: dlt-system-processes.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Lassi Marttala ** +** Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dlt-system.h" + +// Modes of sending +#define SEND_MODE_OFF 0 +#define SEND_MODE_ONCE 1 +#define SEND_MODE_ON 2 + +extern DltSystemThreads threads; + +DLT_IMPORT_CONTEXT(dltsystem) +DLT_DECLARE_CONTEXT(procContext) + +void send_process(LogProcessOptions popts, int n) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-processes, send process info.")); + FILE * pFile; + struct dirent *dp; + char filename[256]; + char buffer[1024]; + int bytes; + int found = 0; + + /* go through all process files in directory */ + DIR *dir = opendir("/proc"); + if(dir>0) + { + while ((dp=readdir(dir)) != NULL) + { + if(isdigit(dp->d_name[0])) + { + buffer[0] = 0; + sprintf(filename, "/proc/%s/cmdline",dp->d_name); + pFile = fopen(filename, "r"); + if(pFile>0) + { + bytes = fread(buffer, 1, sizeof(buffer)-1, pFile); + fclose(pFile); + } + if((strcmp(popts.Name[n], "*")==0) || + (strcmp(buffer, popts.Name[n])==0)) + { + found = 1; + sprintf(filename, "/proc/%s/%s", dp->d_name,popts.Filename[n]); + pFile = fopen(filename, "r"); + if(pFile>0) + { + bytes = fread(buffer, 1, sizeof(buffer)-1, pFile); + fclose(pFile); + + if(bytes>0) + { + buffer[bytes] = 0; + DLT_LOG(procContext, DLT_LOG_INFO, DLT_INT(atoi(dp->d_name)), DLT_STRING(popts.Filename[n]), DLT_STRING(buffer)); + } + } + if(strcmp(popts.Name[n], "*") !=0) + break; + } + } + } + closedir(dir); + } + + if(!found) { + DLT_LOG(procContext, DLT_LOG_INFO, DLT_STRING("Process"), DLT_STRING(popts.Name[n]),DLT_STRING("not running!")); + } +} + +void logprocess_thread(void *v_conf) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-processes, in thread.")); + + DltSystemConfiguration *conf = (DltSystemConfiguration *) v_conf; + DLT_REGISTER_CONTEXT(procContext, conf->LogProcesses.ContextId, "Log Processes"); + + int process_delays[DLT_SYSTEM_LOG_PROCESSES_MAX]; + int i; + for(i = 0;i < conf->LogProcesses.Count;i++) + process_delays[i] = conf->LogProcesses.TimeDelay[i]; + + while(!threads.shutdown) + { + sleep(1); + for(i = 0;i < conf->LogProcesses.Count;i++) + { + if(conf->LogProcesses.Mode[i] == SEND_MODE_OFF) + continue; + + if(process_delays[i] <= 0) + { + send_process(conf->LogProcesses, i); + process_delays[i] = conf->LogProcesses.TimeDelay[i]; + if(conf->LogProcesses.Mode[i] == SEND_MODE_ONCE) + conf->LogProcesses.Mode[i] = SEND_MODE_OFF; + } + else + { + process_delays[i]--; + } + } + } +} + +void start_logprocess(DltSystemConfiguration *conf) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-processes, starting process log.")); + static pthread_attr_t t_attr; + static pthread_t pt; + pthread_create(&pt, &t_attr, (void *)logprocess_thread, conf); + threads.threads[threads.count++] = pt; +} diff --git a/src/system/dlt-system-shell.c b/src/system/dlt-system-shell.c new file mode 100644 index 0000000..758f5fc --- /dev/null +++ b/src/system/dlt-system-shell.c @@ -0,0 +1,104 @@ +/** + * @licence app begin@ + * Copyright (C) 2012 BMW AG + * + * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * + * \author Lassi Marttala BMW 2012 + * + * \file dlt-system-logfile.c + * For further information see http://www.genivi.org/. + * @licence end@ + */ + +/******************************************************************************* +** ** +** SRC-MODULE: dlt-system-shell.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Lassi Marttala ** +** Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + +/******************************************************************************* +** Author Identity ** +******************************************************************************** +** ** +** Initials Name Company ** +** -------- ------------------------- ---------------------------------- ** +** lm Lassi Marttala BMW ** +*******************************************************************************/ +#include "dlt.h" +#include "dlt-system.h" + +#include +#include + +DLT_IMPORT_CONTEXT(dltsystem) +DLT_DECLARE_CONTEXT(shellContext) + +int dlt_shell_injection_callback(uint32_t service_id, void *data, uint32_t length) +{ + DLT_LOG(dltsystem,DLT_LOG_DEBUG, + DLT_STRING("dlt-system-shell, injection callback")); + char text[1024]; + int syserr = 0; + + strncpy(text,data,length); + + DLT_LOG(dltsystem,DLT_LOG_DEBUG, + DLT_STRING("dlt-system-shell, injection injection id:"), + DLT_UINT32(service_id)); + DLT_LOG(dltsystem,DLT_LOG_DEBUG, + DLT_STRING("dlt-system-shell, injection data:"), + DLT_STRING(text)); + + switch(service_id) + { + case 0x1001: + if((syserr = system(text)) != 0) + { + DLT_LOG(dltsystem,DLT_LOG_ERROR, + DLT_STRING("dlt-system-shell, abnormal exit status."), + DLT_STRING(text), + DLT_INT(syserr)); + } + break; + default: + DLT_LOG(dltsystem,DLT_LOG_ERROR, + DLT_STRING("dlt-system-shell, unknown command received."), + DLT_UINT32(service_id), + DLT_STRING(text)); + break; + } + return 0; +} + +void init_shell() +{ + DLT_LOG(dltsystem,DLT_LOG_DEBUG, + DLT_STRING("dlt-system-shell, register callback")); + DLT_REGISTER_CONTEXT(shellContext,"CMD","Execute Shell commands"); + DLT_REGISTER_INJECTION_CALLBACK(shellContext, 0x1001, dlt_shell_injection_callback); +} diff --git a/src/system/dlt-system-syslog.c b/src/system/dlt-system-syslog.c new file mode 100644 index 0000000..2e958f2 --- /dev/null +++ b/src/system/dlt-system-syslog.c @@ -0,0 +1,153 @@ +/** + * @licence app begin@ + * Copyright (C) 2012 BMW AG + * + * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. + * + * Contributions are licensed to the GENIVI Alliance under one or more + * Contribution License Agreements. + * + * \copyright + * This Source Code Form is subject to the terms of the + * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with + * this file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * + * \author Lassi Marttala BMW 2012 + * + * \file dlt-system-logfile.c + * For further information see http://www.genivi.org/. + * @licence end@ + */ + +/******************************************************************************* +** ** +** SRC-MODULE: dlt-system-syslog.c ** +** ** +** TARGET : linux ** +** ** +** PROJECT : DLT ** +** ** +** AUTHOR : Lassi Marttala ** +** Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** ** +** PURPOSE : ** +** ** +** REMARKS : ** +** ** +** PLATFORM DEPENDANT [yes/no]: yes ** +** ** +** TO BE CHANGED BY USER [yes/no]: no ** +** ** +*******************************************************************************/ + + +#include +#include +#include +#include +#include +#include + +#include "dlt-system.h" + +extern DltSystemThreads threads; + +DLT_IMPORT_CONTEXT(dltsystem) +DLT_DECLARE_CONTEXT(syslogContext) +#define RECV_BUF_SZ 1024 + +int init_socket(SyslogOptions opts) +{ + DLT_LOG(dltsystem,DLT_LOG_DEBUG, + DLT_STRING("dlt-system-syslog, init socket, port: "), + DLT_INT(opts.Port)); + + int sock = -1; + struct sockaddr_in syslog_addr; + + sock = socket(AF_INET, SOCK_DGRAM, 0); + if(sock < 0) + { + DLT_LOG(syslogContext, DLT_LOG_FATAL, + DLT_STRING("Unable to create socket for SYSLOG.")); + return -1; + } + + syslog_addr.sin_family = AF_INET; + syslog_addr.sin_port = htons(opts.Port); + syslog_addr.sin_addr.s_addr = INADDR_ANY; + bzero(&(syslog_addr.sin_zero), 8); + + if (bind(sock, (struct sockaddr *)&syslog_addr, + sizeof(struct sockaddr)) == -1) + { + DLT_LOG(syslogContext, DLT_LOG_FATAL, + DLT_STRING("Unable to bind socket for SYSLOG.")); + return -1; + } + + return sock; +} + +int read_socket(int sock) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-syslog, read socket")); + char recv_data[RECV_BUF_SZ]; + struct sockaddr_in client_addr; + socklen_t addr_len = sizeof(struct sockaddr_in); + + int bytes_read = recvfrom(sock, recv_data, RECV_BUF_SZ, 0, + (struct sockaddr *) &client_addr, &addr_len); + if(bytes_read == -1) + { + if(errno == EINTR) + { + return 0; + } + else + { + DLT_LOG(syslogContext, DLT_LOG_FATAL, + DLT_STRING("Read from socket failed in SYSLOG.")); + return -1; + } + } + + recv_data[bytes_read] = '\0'; + + if(bytes_read != 0) + { + DLT_LOG(syslogContext, DLT_LOG_INFO, DLT_STRING(recv_data)); + } + return bytes_read; +} + +void syslog_thread(void *v_conf) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-syslog, in thread.")); + + DltSystemConfiguration *conf = (DltSystemConfiguration *) v_conf; + DLT_REGISTER_CONTEXT(syslogContext, conf->Syslog.ContextId, "SYSLOG Adapter") + + int sock = init_socket(conf->Syslog); + if(sock < 0) + return; + + while(!threads.shutdown) + { + if(read_socket(sock) < 0) + return; + } +} + +void start_syslog(DltSystemConfiguration *conf) +{ + DLT_LOG(dltsystem, DLT_LOG_DEBUG, + DLT_STRING("dlt-system-syslog, start syslog")); + static pthread_attr_t t_attr; + static pthread_t pt; + pthread_create(&pt, &t_attr, (void *)syslog_thread, conf); + threads.threads[threads.count++] = pt; +} diff --git a/src/system/dlt-system.c b/src/system/dlt-system.c old mode 100755 new mode 100644 index b04cdfb..6e1d22e --- a/src/system/dlt-system.c +++ b/src/system/dlt-system.c @@ -13,7 +13,7 @@ * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * - * \author Alexander Wenzel BMW 2011-2012 + * \author Lassi Marttala BMW 2012 * * \file dlt-system.c * For further information see http://www.genivi.org/. @@ -28,7 +28,8 @@ ** ** ** PROJECT : DLT ** ** ** -** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** AUTHOR : Lassi Marttala ** +** Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** ** ** ** PURPOSE : ** ** ** @@ -40,722 +41,57 @@ ** ** *******************************************************************************/ -/******************************************************************************* -** Author Identity ** -******************************************************************************** -** ** -** Initials Name Company ** -** -------- ------------------------- ---------------------------------- ** -** aw Alexander Wenzel BMW ** -*******************************************************************************/ - -/******************************************************************************* -** Revision Control History ** -*******************************************************************************/ +#include "dlt-system.h" #include -#include #include -#include -#include -#include -#include -#include #include +#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "dlt_common.h" -#include "dlt_user.h" - -#include "dlt-system.h" -#include "dlt-system_cfg.h" -#include "dlt-system-log.h" - -/* Port number, to which the syslogd-ng sends its log messages */ -#define MAXSTRLEN 1024 - -DLT_DECLARE_CONTEXT(syslogContext); -DLT_DECLARE_CONTEXT(processesContext); -DLT_DECLARE_CONTEXT(filetransferContext); -DLT_DECLARE_CONTEXT(shellContext); -DltContext logFileContext[DLT_SYSTEM_LOG_FILE_MAX]; - -DltSystemOptions options; -DltSystemRuntime runtime; - -void dlt_system_init_options(DltSystemOptions *options) -{ - int num; - - strncpy(options->ConfigurationFile,DEFAULT_CONFIGURATION_FILE,sizeof(options->ConfigurationFile)); - strncpy(options->ApplicationId,DEFAULT_APPLICATION_ID,sizeof(options->ApplicationId)); - options->daemonise = 0; - - /* Syslog Adapter */ - options->SyslogEnable = 0; - strncpy(options->SyslogContextId,DEFAULT_SYSLOG_CONTEXT_ID,sizeof(options->SyslogContextId)); - options->SyslogPort = DEFAULT_SYSLOG_PORT; - - /* Filetransfer */ - options->FiletransferEnable = 0; - options->FiletransferCompression1 = 1; - options->FiletransferCompression2 = 0; - options->FiletransferCompressionLevel = 5; - strncpy(options->FiletransferContextId,DEFAULT_FILETRANSFER_CONTEXT_ID,sizeof(options->FiletransferContextId)); - strncpy(options->FiletransferDirectory1,DEFAULT_FILETRANSFER_DIRECTORY,sizeof(options->FiletransferDirectory1)); - options->FiletransferDirectory2[0]=0; - options->FiletransferTimeStartup = DEFAULT_FILETRANSFER_TIME_STARTUP; - options->FiletransferTimeDelay = DEFAULT_FILETRANSFER_TIME_DELAY; - options->FiletransferTimeoutBetweenLogs = DEFAULT_FILETRANSFER_TIMEOUT_BETWEEN_LOGS; - - /* Log file */ - options->LogFileEnable = 0; - options->LogFileNumber = 0; - for(num=0;numLogFileFilename[num][0]=0; - options->LogFileMode[num]=0; - options->LogFileContextId[num][0]=0; - options->LogFileTimeDelay[num]=0; - } - - /* Log processes */ - options->LogProcessesEnable = 0; - strncpy(options->LogProcessesContextId,DEFAULT_LOG_PROCESSES_CONTEXT_ID,sizeof(options->LogProcessesContextId)); - options->LogProcessNumber = 0; - for(num=0;numLogProcessName[num][0]=0; - options->LogProcessFilename[num][0]=0; - options->LogProcessMode[num]=0; - options->LogProcessTimeDelay[num]=0; - } - -} - -int dlt_system_parse_options(DltSystemOptions *options,int argc, char* argv[]) -{ - int opt; - char version[255]; - - while ((opt = getopt(argc, argv, "c:hd")) != -1) - { - switch (opt) - { - case 'd': - { - options->daemonise = 1; - break; - } - case 'c': - { - strncpy(options->ConfigurationFile,optarg,sizeof(options->ConfigurationFile)); - break; - } - case 'h': - { - dlt_get_version(version); - - printf("Usage: dlt-system [options]\n"); - printf("System information manager and forwarder to DLT daemon.\n"); - printf("%s \n", version); - printf("Options:\n"); - printf("-d - Daemonize\n"); - printf("-c filename - Set configuration file (default: /etc/dlt-system.conf)\n"); - printf("-h - This help\n"); - return -1; - break; - } - default: /* '?' */ - { - fprintf(stderr, "Unknown option '%c'\n", optopt); - return -1; - } - } - } - - return 0; -} +DLT_DECLARE_CONTEXT(dltsystem) -int dlt_system_parse_configuration(DltSystemOptions *options) +int main(int argc, char* argv[]) { - FILE * pFile; - char line[1024]; - char token[1024]; - char value[1024]; - char *pch; - - /* open configuration file */ - pFile = fopen (options->ConfigurationFile,"r"); - - if (pFile!=NULL) - { - while(1) - { - /* fetch line from configuration file */ - if ( fgets (line , 1024 , pFile) != NULL ) - { - //printf("Line: %s\n",line); - pch = strtok (line," =\r\n"); - token[0]=0; - value[0]=0; - - while (pch != NULL) - { - if(strcmp(pch,"#")==0) - break; - - if(token[0]==0) - { - strncpy(token,pch,sizeof(token)); - } - else - { - strncpy(value,pch,sizeof(value)); - break; - } - - pch = strtok (NULL, " =\r\n"); - } - - if(token[0] && value[0]) - { - /* parse arguments here */ - if(strcmp(token,"ApplicationId")==0) - { - strncpy(options->ApplicationId,value,sizeof(options->ApplicationId)); - printf("Option: %s=%s\n",token,value); - } - /* Syslog Adapter */ - else if(strcmp(token,"SyslogEnable")==0) - { - options->SyslogEnable = atoi(value); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"SyslogContextId")==0) - { - strncpy(options->SyslogContextId,value,sizeof(options->SyslogContextId)); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"SyslogPort")==0) - { - options->SyslogPort = atoi(value); - printf("Option: %s=%s\n",token,value); - } - /* Filetransfer */ - else if(strcmp(token,"FiletransferEnable")==0) - { - options->FiletransferEnable = atoi(value); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"FiletransferCompression1")==0) - { - options->FiletransferCompression1 = atoi(value); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"FiletransferCompression2")==0) - { - options->FiletransferCompression2 = atoi(value); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"FiletransferCompressionLevel")==0) - { - options->FiletransferCompressionLevel = atoi(value); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"FiletransferDirectory1")==0) - { - strncpy(options->FiletransferDirectory1,value,sizeof(options->FiletransferDirectory1)); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"FiletransferDirectory2")==0) - { - strncpy(options->FiletransferDirectory2,value,sizeof(options->FiletransferDirectory2)); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"FiletransferContextId")==0) - { - strncpy(options->FiletransferContextId,value,sizeof(options->FiletransferContextId)); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"FiletransferTimeStartup")==0) - { - options->FiletransferTimeStartup = atoi(value); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"FiletransferTimeDelay")==0) - { - options->FiletransferTimeDelay = atoi(value); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"FiletransferTimeoutBetweenLogs")==0) - { - options->FiletransferTimeoutBetweenLogs = atoi(value); - printf("Option: %s=%s\n",token,value); - } - /* Log File */ - else if(strcmp(token,"LogFileEnable")==0) - { - options->LogFileEnable = atoi(value); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"LogFileFilename")==0) - { - strncpy(options->LogFileFilename[options->LogFileNumber],value,sizeof(options->LogFileFilename[options->LogFileNumber])); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"LogFileMode")==0) - { - options->LogFileMode[options->LogFileNumber] = atoi(value); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"LogFileTimeDelay")==0) - { - options->LogFileTimeDelay[options->LogFileNumber] = atoi(value); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"LogFileContextId")==0) - { - strncpy(options->LogFileContextId[options->LogFileNumber],value,sizeof(options->LogFileContextId[options->LogFileNumber])); - printf("Option: %s=%s\n",token,value); - if(options->LogFileNumber < (DLT_SYSTEM_LOG_FILE_MAX-1) ) - options->LogFileNumber++; - } - /* Log processes */ - else if(strcmp(token,"LogProcessesEnable")==0) - { - options->LogProcessesEnable = atoi(value); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"LogProcessesContextId")==0) - { - strncpy(options->LogProcessesContextId,value,sizeof(options->LogProcessesContextId)); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"LogProcessName")==0) - { - strncpy(options->LogProcessName[options->LogProcessNumber],value,sizeof(options->LogProcessName[options->LogProcessNumber])); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"LogProcessFilename")==0) - { - strncpy(options->LogProcessFilename[options->LogProcessNumber],value,sizeof(options->LogProcessFilename[options->LogProcessNumber])); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"LogProcessMode")==0) - { - options->LogProcessMode[options->LogProcessNumber] = atoi(value); - printf("Option: %s=%s\n",token,value); - } - else if(strcmp(token,"LogProcessTimeDelay")==0) - { - options->LogProcessTimeDelay[options->LogProcessNumber] = atoi(value); - printf("Option: %s=%s\n",token,value); - if(options->LogProcessNumber < (DLT_SYSTEM_LOG_PROCESSES_MAX-1) ) - options->LogProcessNumber++; - } - else - { - fprintf(stderr, "Unknown option: %s=%s\n",token,value); - } - } + DltSystemCliOptions options; + DltSystemConfiguration config; - } - else - { - break; - } - } - fclose (pFile); - } - else + if(read_command_line(&options, argc, argv) < 0) { - fprintf(stderr, "Cannot open configuration file: %s\n",options->ConfigurationFile); + fprintf(stderr, "Failed to read command line!\n"); return -1; - } - - return 0; -} - -void dlt_system_daemonize() -{ - int i,ret; - //int lfp,bytes_written; - - /* Daemonize */ - i=fork(); - if (i<0) - { - exit(-1); /* fork error */ - } - - if (i>0) - { - exit(0); /* parent exits */ - } - /* child (daemon) continues */ - - /* Process independency */ - - /* obtain a new process group */ - if (setsid()==-1) - { - exit(-1); /* fork error */ - } - - /* Close descriptors */ - for (i=getdtablesize();i>=0;--i) - { - close(i); /* close all descriptors */ - } - - /* Open standard descriptors stdin, stdout, stderr */ - i=open("/dev/null",O_RDWR); /* open stdin */ - ret=dup(i); /* stdout */ - ret=dup(i); /* stderr */ - - /* Set umask */ - //umask(DLT_DAEMON_UMASK); - - /* Change to known directory */ - //ret=chdir(DLT_USER_DIR); - - /* Ensure single copy of daemon; - run only one instance at a time */ -#if 0 - lfp=open(DLT_DAEMON_LOCK_FILE,O_RDWR|O_CREAT,DLT_DAEMON_LOCK_FILE_PERM); - if (lfp<0) - { - dlt_log(LOG_CRIT, "can't open lock file, exiting DLT daemon\n"); - exit(-1); /* can not open */ - } - if (lockf(lfp,F_TLOCK,0)<0) - { - dlt_log(LOG_CRIT, "can't lock lock file, exiting DLT daemon\n"); - exit(-1); /* can not lock */ - } - /* only first instance continues */ - - sprintf(str,"%d\n",getpid()); - bytes_written=write(lfp,str,strlen(str)); /* record pid to lockfile */ - -#endif - /* Catch signals */ - signal(SIGCHLD,SIG_IGN); /* ignore child */ - signal(SIGTSTP,SIG_IGN); /* ignore tty signals */ - signal(SIGTTOU,SIG_IGN); - signal(SIGTTIN,SIG_IGN); - -} /* dlt_system_daemonize() */ - -void dlt_system_cleanup() -{ - int num; - - if(options.SyslogEnable) - DLT_UNREGISTER_CONTEXT(syslogContext); - - if(options.FiletransferEnable) - DLT_UNREGISTER_CONTEXT(filetransferContext); - - if(options.LogFileEnable) { - for(num=0;num0) - { - } - - return 0; -} - -int main(int argc, char* argv[]) -{ - int sock = -1; - int bytes_read; - socklen_t addr_len; - char recv_data[MAXSTRLEN]; - struct sockaddr_in client_addr, server_addr; - fd_set master_rfds; - fd_set read_rfds; - int fdmax; - struct timeval tv; - int retval; - uint32_t lasttime; - int firsttime = 1; - int num; - - /* init options */ - dlt_system_init_options(&options); - - /* parse command line options */ - if(dlt_system_parse_options(&options,argc,argv)) { - return -1; } - if(options.daemonise) + if(read_configuration_file(&config, options.ConfigurationFileName) < 0) { - dlt_system_daemonize(); - } - - /* set signal handler */ - signal(SIGTERM, dlt_system_signal_handler); /* software termination signal from kill */ - signal(SIGHUP, dlt_system_signal_handler); /* hangup signal */ - signal(SIGQUIT, dlt_system_signal_handler); - signal(SIGINT, dlt_system_signal_handler); - - /* parse configuration file */ - if(dlt_system_parse_configuration(&options)) { - return -1; - } - - /* register application and contexts */ - DLT_REGISTER_APP(options.ApplicationId,"DLT System Manager"); - if(options.SyslogEnable) - DLT_REGISTER_CONTEXT(syslogContext,options.SyslogContextId,"SYSLOG Adapter"); - if(options.FiletransferEnable) - DLT_REGISTER_CONTEXT(filetransferContext,options.FiletransferContextId,"Filetransfer"); - if(options.LogFileEnable) { - for(num=0;numfdmax) - fdmax=sock; + fprintf(stderr, "Failed to read configuration file!\n"); + return -1; } + DLT_REGISTER_APP(config.ApplicationId, "DLT System Manager"); + DLT_REGISTER_CONTEXT(dltsystem,"MGR", "Context of main dlt system manager"); + sleep(1); + DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("Configuration loaded.")); - /* init timers */ - lasttime = dlt_uptime(); - runtime.timeStartup = 0; - runtime.timeFiletransferDelay = 0; - - /* initialise filetransfer manager */ - if(options.FiletransferEnable) + if(options.Daemonize > 0) { - if(dlt_system_filetransfer_init(&options,&runtime) < 0) + if(daemonize() < 0) { - fprintf(stderr, "Error initializing filetransfer:\n%s\n", strerror(errno)); + DLT_LOG(dltsystem, DLT_LOG_FATAL, DLT_STRING("Daemonization failed!")); return -1; } + DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("dlt-system daemonized.")); } + DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("Setting signal handlers for abnormal exit")); + signal(SIGTERM, dlt_system_signal_handler); + signal(SIGHUP, dlt_system_signal_handler); + signal(SIGQUIT, dlt_system_signal_handler); + signal(SIGINT, dlt_system_signal_handler); - while (1) - { - /* Wait up to one second. */ - tv.tv_sec = 0; - if(runtime.filetransferRunning) - tv.tv_usec = 20000; - else - tv.tv_usec = (dlt_uptime()-lasttime+10000)*100; - - /* wait data to be received, or wait min time */ - read_rfds = master_rfds; - retval = select(fdmax+1, &read_rfds, NULL, NULL, &tv); + DLT_LOG(dltsystem, DLT_LOG_DEBUG, DLT_STRING("Launching threads.")); - if (retval == -1) - perror("select()"); - else if (retval) - ;//printf("Data is available now.\n"); - else - ;//printf("No data within one seconds.\n"); - - /* call filtransfer even in shorter time schedule */ - if(options.FiletransferEnable && runtime.filetransferRunning) - dlt_system_filetransfer_run(&options,&runtime,&filetransferContext); - - if((dlt_uptime()-lasttime) >= 10000) - { - /* one second elapsed */ - lasttime = dlt_uptime(); - runtime.timeStartup++; - - /* filetransfer manager */ - if(options.FiletransferEnable) { - if(runtime.timeStartup > options.FiletransferTimeStartup) { - if(runtime.timeFiletransferDelay>0) { - runtime.timeFiletransferDelay--; - } - else { - dlt_system_filetransfer_run(&options,&runtime,&filetransferContext); - } - } - } - - /* log files */ - if(options.LogFileEnable) { - for(num=0;num BMW 2011-2012 + * \author Lassi Marttala BMW 2012 * - * \file dlt-system.h + * \file dlt-system.c * For further information see http://www.genivi.org/. * @licence end@ */ - /******************************************************************************* ** ** ** SRC-MODULE: dlt-system.h ** @@ -29,7 +28,7 @@ ** ** ** PROJECT : DLT ** ** ** -** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** +** AUTHOR : Lassi Marttala ** ** ** ** PURPOSE : ** ** ** @@ -47,80 +46,121 @@ ** ** ** Initials Name Company ** ** -------- ------------------------- ---------------------------------- ** -** aw Alexander Wenzel BMW ** +** lm Lassi Marttala BMW ** *******************************************************************************/ -/******************************************************************************* -** Revision Control History ** -*******************************************************************************/ +#ifndef DLT_SYSTEM_H_ +#define DLT_SYSTEM_H_ -#ifndef DLT_SYSTEM_H -#define DLT_SYSTEM_H +// DLT related includes. +#include "dlt.h" +#include "dlt_common.h" + +// Constants +#define DEFAULT_CONF_FILE "/etc/dlt-system.conf" +#define DLT_SYSTEM_LOG_FILE_MAX 32 +#define DLT_SYSTEM_LOG_DIRS_MAX 32 +#define DLT_SYSTEM_LOG_PROCESSES_MAX 32 #define DLT_SYSTEM_MODE_OFF 0 #define DLT_SYSTEM_MODE_STARTUP 1 #define DLT_SYSTEM_MODE_REGULAR 2 -#define DLT_SYSTEM_LOG_FILE_MAX 32 -#define DLT_SYSTEM_LOG_PROCESSES_MAX 32 +#define MAX_LINE 1024 + +#define MAX_THREADS 8 + +/** + * Configuration structures. + * Please see dlt-system.conf for explanation of all the options. + */ + +// Command line options +typedef struct { + char *ConfigurationFileName; + int Daemonize; +} DltSystemCliOptions; + +// Configuration file options +typedef struct { + int Enable; + char *ContextId; + int Port; +} SyslogOptions; typedef struct { - char ConfigurationFile[256]; - char ApplicationId[256]; - int daemonise; - - int SyslogEnable; /*# Enable the Syslog Adapter (Default: 0)*/ - char SyslogContextId[256]; /*# The Context Id of the syslog adapter (Default: SYSL)*/ - int SyslogPort; /*# The UDP port opened by DLT system mamager to receive system logs (Default: 47111)*/ - - int FiletransferEnable; /*# Enable the Filetransfer (Default: 0)*/ - int FiletransferCompression1; /*# Enable the Filetransfer compression for dir 1 (Default: 1)*/ - int FiletransferCompression2; /*# Enable the Filetransfer compression for dir 2 (Default: 0)*/ - int FiletransferCompressionLevel; /*# Set the compression level between 0-9 (Default: 5)*/ - char FiletransferDirectory1[256]; /*# Directory which contains files to be transfered over DLT (Default: /tmp/filetransfer)# Files are deleted after Filetransfer is finished and after TimeDelay expired*/ - char FiletransferDirectory2[256]; - char FiletransferContextId[256]; /*# The Context Id of the filetransfer (Default: FILE)*/ - int FiletransferTimeStartup; /*# Time after startup of dlt-system when first file is transfered (Default: 30)# Time in seconds*/ - int FiletransferTimeDelay; /*# Time to wait when transfered file is deleted and next file transfer starts (Default: 10)# Time in seconds*/ - int FiletransferTimeoutBetweenLogs;/*# Waits a period of time between two file transfer logs of a single file to DLT to ensure that the FIFO of DLT is not flooded.*/ - - /*# Log different files - # Mode: 0 = off, 1 = startup only, 2 = regular - # TimeDelay: If mode regular is set, time delay is the number of seconds for next sent - */ - int LogFileEnable; /*# Enable the logging of files (Default: 0)*/ - int LogFileNumber; - char LogFileFilename[DLT_SYSTEM_LOG_FILE_MAX][256]; - int LogFileMode[DLT_SYSTEM_LOG_FILE_MAX]; - int LogFileTimeDelay[DLT_SYSTEM_LOG_FILE_MAX]; - char LogFileContextId[DLT_SYSTEM_LOG_FILE_MAX][256]; - - int LogProcessesEnable; /*# Enable the logging of processes (Default: 0)*/ - char LogProcessesContextId[256]; /*# The Context Id of the kernel version (Default: PROC)*/ - - /*# Log different processes - # Name: * = all process, X=alternative name (must correspind to /proc/X/cmdline - # Filename: the filename in the subdirectory /proc/processid/ - # Mode: 0 = off, 1 = startup only, 2 = regular - # TimeDelay: If mode regular is set, time delay is the number of seconds for next sent - */ - int LogProcessNumber; - char LogProcessName[DLT_SYSTEM_LOG_PROCESSES_MAX][256]; - char LogProcessFilename[DLT_SYSTEM_LOG_PROCESSES_MAX][256]; - int LogProcessMode[DLT_SYSTEM_LOG_PROCESSES_MAX]; - int LogProcessTimeDelay[DLT_SYSTEM_LOG_PROCESSES_MAX]; -} DltSystemOptions; + int Enable; + char *ContextId; + int TimeStartup; + int TimeDelay; + int TimeoutBetweenLogs; + char *TempDir; + + // Variable number of file transfer dirs + int Count; + int Compression[DLT_SYSTEM_LOG_DIRS_MAX]; + int CompressionLevel[DLT_SYSTEM_LOG_DIRS_MAX]; + char *Directory[DLT_SYSTEM_LOG_DIRS_MAX]; +} FiletransferOptions; typedef struct { - int timeStartup; /* time in seconds since startup of dlt-system */ - int timeFiletransferDelay; /* time in seconds to start next filetransfer */ - char filetransferFile[256]; - long int filetransferFilesize; - int timeLogFileDelay[DLT_SYSTEM_LOG_FILE_MAX]; /* time in seconds to start next file log */ - int timeLogProcessDelay[DLT_SYSTEM_LOG_PROCESSES_MAX]; /* time in seconds to start next process log */ - int filetransferRunning; /* 0 = stooped, 1 = running */ - int filetransferCountPackages; /* number of packets to be transfered */ - int filetransferLastSentPackage; /* last packet sent starting from 1 */ -} DltSystemRuntime; - -#endif /* DLT_SYSTEM_H */ + int Enable; + + // Variable number of files to transfer + int Count; + char *ContextId[DLT_SYSTEM_LOG_FILE_MAX]; + char *Filename[DLT_SYSTEM_LOG_FILE_MAX]; + int Mode[DLT_SYSTEM_LOG_FILE_MAX]; + int TimeDelay[DLT_SYSTEM_LOG_FILE_MAX]; +} LogFileOptions; + +typedef struct { + int Enable; + char *ContextId; + + // Variable number of processes + int Count; + char *Name[DLT_SYSTEM_LOG_PROCESSES_MAX]; + char *Filename[DLT_SYSTEM_LOG_PROCESSES_MAX]; + int Mode[DLT_SYSTEM_LOG_PROCESSES_MAX]; + int TimeDelay[DLT_SYSTEM_LOG_PROCESSES_MAX]; +} LogProcessOptions; + +typedef struct { + char *ApplicationId; + SyslogOptions Syslog; + FiletransferOptions Filetransfer; + LogFileOptions LogFile; + LogProcessOptions LogProcesses; +} DltSystemConfiguration; + +typedef struct { + pthread_t threads[MAX_THREADS]; + int count; + int shutdown; +} DltSystemThreads; + +/** + * Forward declarations for the whole application + */ + +// In dlt-system-options.c +int read_command_line(DltSystemCliOptions *options, int argc, char *argv[]); +int read_configuration_file(DltSystemConfiguration *config, char *file_name); + +// In dlt-process-handling.c +int daemonize(); +void start_threads(DltSystemConfiguration *config); +void join_threads(); +void dlt_system_signal_handler(int sig); +void register_with_dlt(DltSystemConfiguration *config); + +// Thread initiators: +void init_shell(); +void start_syslog(); +void start_filetransfer(DltSystemConfiguration *conf); +void start_logfile(DltSystemConfiguration *conf); +void start_logprocess(DltSystemConfiguration *conf); + + +#endif /* DLT_SYSTEM_H_ */ diff --git a/src/system/dlt-system_cfg.h b/src/system/dlt-system_cfg.h deleted file mode 100644 index 79ce5e4..0000000 --- a/src/system/dlt-system_cfg.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @licence app begin@ - * Copyright (C) 2012 BMW AG - * - * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. - * - * Contributions are licensed to the GENIVI Alliance under one or more - * Contribution License Agreements. - * - * \copyright - * This Source Code Form is subject to the terms of the - * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with - * this file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * - * \author Alexander Wenzel BMW 2011-2012 - * - * \file dlt-system_cfg.h - * For further information see http://www.genivi.org/. - * @licence end@ - */ - - -/******************************************************************************* -** ** -** SRC-MODULE: dlt-system_cfg.h ** -** ** -** TARGET : linux ** -** ** -** PROJECT : DLT ** -** ** -** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** -** ** -** PURPOSE : ** -** ** -** REMARKS : ** -** ** -** PLATFORM DEPENDANT [yes/no]: yes ** -** ** -** TO BE CHANGED BY USER [yes/no]: no ** -** ** -*******************************************************************************/ - -/******************************************************************************* -** Author Identity ** -******************************************************************************** -** ** -** Initials Name Company ** -** -------- ------------------------- ---------------------------------- ** -** aw Alexander Wenzel BMW ** -*******************************************************************************/ - -/******************************************************************************* -** Revision Control History ** -*******************************************************************************/ - -#define DEFAULT_CONFIGURATION_FILE "/etc/dlt-system.conf" -#define DEFAULT_APPLICATION_ID "SYS" - -#define DEFAULT_SYSLOG_CONTEXT_ID "SYSL" -#define DEFAULT_SYSLOG_PORT 47111 - -#define DEFAULT_FILETRANSFER_DIRECTORY "/tmp/filetransfer" -#define DEFAULT_FILETRANSFER_CONTEXT_ID "FILE" -#define DEFAULT_FILETRANSFER_TIME_STARTUP 30 -#define DEFAULT_FILETRANSFER_TIME_DELAY 10 -#define DEFAULT_FILETRANSFER_TIMEOUT_BETWEEN_LOGS 10 -#define DEFAULT_LOG_PROCESSES_CONTEXT_ID "PROC" -- cgit v1.2.1