"Fossies" - the Fresh Open Source Software Archive

Member "jpilot-2_0_1/log.c" (3 Apr 2021, 6094 Bytes) of package /linux/privat/jpilot-2_0_1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "log.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.8.2_vs_2_0_1.

    1 /*******************************************************************************
    2  * log.c
    3  * A module of J-Pilot http://jpilot.org
    4  *
    5  * Copyright (C) 1999-2014 by Judd Montgomery
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; version 2 of the License.
   10  *
   11  * This program is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   14  * GNU General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU General Public License
   17  * along with this program; if not, write to the Free Software
   18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   19  ******************************************************************************/
   20 /*
   21  * Thanks to Jason Day for his patches that allowed plugins to log correctly
   22  */
   23 /********************************* Includes ***********************************/
   24 #include "config.h"
   25 #include <stdlib.h>
   26 #include <stdio.h>
   27 #include <stdarg.h>
   28 #include <string.h>
   29 #include <sys/types.h>
   30 #include <sys/stat.h>
   31 #ifdef USE_FLOCK
   32 #  include <sys/file.h>
   33 #else
   34 #  include <fcntl.h>
   35 #endif
   36 #include <signal.h>
   37 #include <utime.h>
   38 
   39 #include "i18n.h"
   40 #include "log.h"
   41 #include "utils.h"
   42 #include "sync.h"
   43 #include "prefs.h"
   44 
   45 /********************************* Constants **********************************/
   46 #define WRITE_MAX_BUF 4096
   47 
   48 /******************************* Global vars **********************************/
   49 extern int pipe_to_parent;
   50 
   51 int glob_log_file_mask;
   52 int glob_log_stdout_mask;
   53 int glob_log_gui_mask;
   54 
   55 extern void output_to_pane(const char *str);
   56 extern pid_t jpilot_master_pid;
   57 
   58 /****************************** Prototypes ************************************/
   59 static int jp_vlogf (int level, const char *format, va_list val);
   60 
   61 /****************************** Main Code *************************************/
   62 int jp_logf(int level, const char *format, ...)
   63 {
   64    va_list val;
   65    int rval;
   66 
   67    if (!((level & glob_log_file_mask) ||
   68        (level & glob_log_stdout_mask) ||
   69        (level & glob_log_gui_mask))) {
   70       return EXIT_SUCCESS;
   71    }
   72 
   73    va_start(val, format);
   74    rval = jp_vlogf(level, format, val);
   75    va_end(val);
   76    return rval;
   77 }
   78 
   79 static int jp_vlogf (int level, const char *format, va_list val) {
   80    char                 real_buf[WRITE_MAX_BUF+32];
   81    char                 *buf, *local_buf;
   82    int                  size;
   83    int                  len;
   84    static FILE          *fp=NULL;
   85    static int           err_count=0;
   86    char                 cmd[16];
   87 
   88    if (!((level & glob_log_file_mask) ||
   89          (level & glob_log_stdout_mask) ||
   90          (level & glob_log_gui_mask))) {
   91       return EXIT_SUCCESS;
   92    }
   93 
   94    if ((!fp) && (err_count>10)) {
   95       return EXIT_FAILURE;
   96    }
   97    if ((!fp) && (err_count==10)) {
   98       fprintf(stderr, _("Unable to open log file, giving up.\n"));
   99       err_count++;
  100       return EXIT_FAILURE;
  101    }
  102    if ((!fp) && (err_count<10)) {
  103       char fullname[FILENAME_MAX];
  104       get_home_file_name(EPN".log", fullname, sizeof(fullname));
  105 
  106       fp = fopen(fullname, "w");
  107       if (!fp) {
  108          fprintf(stderr, _("Unable to open log file\n"));
  109          err_count++;
  110       }
  111    }
  112 
  113    buf=&(real_buf[16]);
  114    buf[0] = '\0';
  115 
  116    size = g_vsnprintf(buf, WRITE_MAX_BUF, format, val);
  117    /* glibc >2.1 can return size > WRITE_MAX_BUF */
  118    /* just in case g_vsnprintf reached the max */
  119    buf[WRITE_MAX_BUF-1] = '\0';
  120    size=strlen(buf);
  121 
  122    local_buf = buf;
  123    /* UTF-8 text so transform in local encoding */
  124    if (g_utf8_validate(buf, -1, NULL))
  125    {
  126       local_buf = g_locale_from_utf8(buf, -1, NULL, NULL, NULL);
  127       if (NULL == local_buf)
  128          local_buf = buf;
  129    }
  130 
  131    if ((fp) && (level & glob_log_file_mask)) {
  132       fwrite(local_buf, size, 1, fp);
  133       fflush(fp);
  134    }
  135 
  136    if (level & glob_log_stdout_mask) {
  137       fputs(local_buf, stdout);
  138    }
  139 
  140    /* free the buffer is a conversion was used */
  141    if (local_buf != buf)
  142       g_free(local_buf);
  143 
  144    if ((pipe_to_parent) && (level & glob_log_gui_mask)) {
  145       /* do not use a pipe for intra-process log
  146        * otherwise we may have a dead lock (jpilot freezes) */
  147       if (getpid() == jpilot_master_pid)
  148          output_to_pane(buf);
  149       else {
  150          sprintf(cmd, "%d:", PIPE_PRINT);
  151          len = strlen(cmd);
  152          buf = buf-len;
  153          strncpy(buf, cmd, len);
  154          size += len;
  155          buf[size]='\0';
  156          buf[size+1]='\n';
  157          size += 2;
  158          if (write(pipe_to_parent, buf, size) < 0) {
  159             fprintf(stderr, "write returned error %s %d\n", __FILE__, __LINE__);
  160          }
  161       }
  162    }
  163 
  164    return EXIT_SUCCESS;
  165 }
  166 
  167 /*
  168  * This function writes data to the parent process.
  169  * A line feed, or a null must be the last character written.
  170  */
  171 int write_to_parent(int command, const char *format, ...)
  172 {
  173    va_list val;
  174    int len, size;
  175    char real_buf[WRITE_MAX_BUF+32];
  176    char *buf;
  177    char cmd[20];
  178 
  179    buf=&(real_buf[16]);
  180    buf[0] = '\0';
  181 
  182    va_start(val, format);
  183    g_vsnprintf(buf, WRITE_MAX_BUF, format, val);
  184    /* glibc >2.1 can return size > WRITE_MAX_BUF */
  185    /* just in case g_vsnprintf reached the max */
  186    buf[WRITE_MAX_BUF-1] = '\0';
  187    size=strlen(buf);
  188    va_end(val);
  189 
  190    /* This is for jpilot-sync */
  191    if (pipe_to_parent==STDOUT_FILENO) {
  192       if (command==PIPE_PRINT) {
  193          if (write(pipe_to_parent, buf, strlen(buf)) < 0) {
  194             jp_logf(JP_LOG_WARN, "write failed %s %d\n", __FILE__, __LINE__);
  195          }
  196       }
  197       return TRUE;
  198    }
  199 
  200    sprintf(cmd, "%d:", command);
  201    len = strlen(cmd);
  202    buf = buf-len;
  203    strncpy(buf, cmd, len);
  204    size += len;
  205    /* The pipe doesn't flush unless a CR is written */
  206    /* This is our key to the parent for a record separator */
  207    buf[size]='\0';
  208    buf[size+1]='\n';
  209    size += 2;
  210    if (write(pipe_to_parent, buf, size) < 0) {
  211       jp_logf(JP_LOG_WARN, "write failed %s %d\n", __FILE__, __LINE__);
  212    }
  213 
  214    return TRUE;
  215 }