"Fossies" - the Fresh Open Source Software Archive

Member "fdupes-2.1.2/log.c" (12 Aug 2020, 4381 Bytes) of package /linux/privat/fdupes-2.1.2.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.

    1 /* Copyright (c) 2018 Adrian Lopez
    2 
    3    This software is provided 'as-is', without any express or implied
    4    warranty. In no event will the authors be held liable for any damages
    5    arising from the use of this software.
    6 
    7    Permission is granted to anyone to use this software for any purpose,
    8    including commercial applications, and to alter it and redistribute it
    9    freely, subject to the following restrictions:
   10 
   11    1. The origin of this software must not be misrepresented; you must not
   12       claim that you wrote the original software. If you use this software
   13       in a product, an acknowledgment in the product documentation would be
   14       appreciated but is not required.
   15    2. Altered source versions must be plainly marked as such, and must not be
   16       misrepresented as being the original software.
   17    3. This notice may not be removed or altered from any source distribution. */
   18 
   19 #include <stdlib.h>
   20 #include <string.h>
   21 #include <time.h>
   22 #include "fmatch.h"
   23 #include "dir.h"
   24 #include "log.h"
   25 
   26 #define LOG_HEADER "[fdupes log]\n"
   27 
   28 /* Open log file in append mode. If file exists, make sure it is a valid fdupes log file. 
   29 */
   30 struct log_info *log_open(char *filename, int *error)
   31 {
   32   struct log_info *info;
   33   int is_match;
   34   size_t read;
   35 
   36   info = (struct log_info*) malloc(sizeof(struct log_info));
   37   if (info == 0)
   38   {
   39     if (error != 0)
   40       *error = LOG_ERROR_OUT_OF_MEMORY;
   41 
   42     return 0;
   43   }
   44 
   45   info->file = fopen(filename, "a+");
   46   if (info->file == 0)
   47   {
   48     if (error != 0)
   49       *error = LOG_ERROR_FOPEN_FAILED;
   50 
   51     free(info);
   52     return 0;
   53   }
   54 
   55   fmatch(info->file, LOG_HEADER, &is_match, &read);
   56   if (!is_match && read > 0)
   57   {
   58     if (error != 0)
   59       *error = LOG_ERROR_NOT_A_LOG_FILE;
   60 
   61     free(info);
   62     return 0;
   63   }
   64 
   65   info->append = read > 0;
   66 
   67   info->log_start = 1;
   68   info->deleted = 0;
   69   info->remaining = 0;
   70 
   71   if (error != 0)
   72     *error = LOG_ERROR_NONE;
   73 
   74   return info;
   75 }
   76 
   77 /* Free linked lists holding set of deleted and remaining files.
   78 */
   79 void log_free_set(struct log_info *info)
   80 {
   81   struct log_file *f;
   82   struct log_file *next;
   83 
   84   f = info->deleted;
   85   while (f != 0)
   86   {
   87     next = f->next;
   88 
   89     free(f);
   90 
   91     f = next;
   92   }
   93 
   94   f = info->remaining;
   95   while (f != 0)
   96   {
   97     next = f->next;
   98 
   99     free(f);
  100 
  101     f = next;
  102   }
  103 
  104   info->deleted = 0;
  105   info->remaining = 0;
  106 }
  107 
  108 /* Signal beginning of duplicate set.
  109 */
  110 void log_begin_set(struct log_info *info)
  111 {
  112   log_free_set(info);
  113 }
  114 
  115 /* Add deleted file to log.
  116 */
  117 int log_file_deleted(struct log_info *info, char *name)
  118 {
  119   struct log_file *file;
  120 
  121   file = (struct log_file*) malloc(sizeof(struct log_file));
  122   if (file == 0)
  123     return 0;
  124 
  125   file->next = info->deleted;
  126   file->filename = name;
  127 
  128   info->deleted = file;
  129 
  130   return 1;
  131 }
  132 
  133 /* Add remaining file to log.
  134 */
  135 int log_file_remaining(struct log_info *info, char *name)
  136 {
  137   struct log_file *file;
  138 
  139   file = (struct log_file*) malloc(sizeof(struct log_file));
  140   if (file == 0)
  141     return 0;
  142 
  143   file->next = info->remaining;
  144   file->filename = name;
  145 
  146   info->remaining = file;
  147 
  148   return 1;
  149 }
  150 
  151 /* Output log header.
  152 */
  153 void log_header(FILE *file)
  154 {
  155   fprintf(file, "%s\n", LOG_HEADER);
  156 }
  157 
  158 /* Output log timestamp.
  159 */
  160 void log_timestamp(FILE *file)
  161 {
  162   time_t t = time(NULL);
  163   struct tm tm = *localtime(&t);
  164 
  165   fprintf(file, "Log entry for %d-%02d-%02d %02d:%02d:%02d\n\n", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
  166 }
  167 
  168 /* Output current working directory.
  169 */
  170 void log_cwd(FILE *file)
  171 {
  172   char *cwd = getworkingdirectory();
  173 
  174   fprintf(file, "working directory:\n  %s\n\n", cwd);
  175 
  176   free(cwd);
  177 }
  178 
  179 /* Signal the end of a duplicate set.
  180 */
  181 void log_end_set(struct log_info *info)
  182 {
  183   struct log_file *f;
  184 
  185   if (info->deleted == 0)
  186     return;
  187 
  188   if (info->log_start)
  189   {
  190     if (info->append)
  191       fprintf(info->file, "---\n\n");
  192     else
  193       log_header(info->file);
  194 
  195     log_timestamp(info->file);
  196     log_cwd(info->file);
  197 
  198     info->log_start = 0;
  199   }
  200 
  201   f = info->deleted;
  202   do
  203   {
  204     fprintf(info->file, "deleted %s\n", f->filename);
  205     f = f->next;
  206   } while (f != 0);
  207 
  208   f = info->remaining;
  209   while (f != 0)
  210   {
  211     fprintf(info->file, "   left %s\n", f->filename);
  212     f = f->next;
  213   }
  214 
  215   fprintf(info->file, "\n");
  216 
  217   fflush(info->file);
  218 }
  219 
  220 /* Close log and free all memory.
  221 */
  222 void log_close(struct log_info *info)
  223 {
  224   fclose(info->file);
  225 
  226   log_free_set(info);
  227 
  228   free(info);
  229 }