/[nmh]/nmh/uip/annosbr.c
ViewVC logotype

Diff of /nmh/uip/annosbr.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by gbburkhardt, Tue Sep 30 16:57:38 2003 UTC revision 1.6 by jon, Wed Dec 7 21:25:47 2005 UTC
# Line 13  Line 13 
13  #include <h/tws.h>  #include <h/tws.h>
14  #include <fcntl.h>  #include <fcntl.h>
15  #include <errno.h>  #include <errno.h>
16    #include <utime.h>
17    
18    
19  /*  /*
# Line 20  Line 21 
21   */   */
22  static int annosbr (int, char *, char *, char *, int, int, int, int);  static int annosbr (int, char *, char *, char *, int, int, int, int);
23    
24    /*
25     *      This "local" global and the annopreserve() function are a hack that allows additional
26     *      functionality to be added to anno without piling on yet another annotate() argument.
27     */
28    
29    static  int     preserve_actime_and_modtime = 0;        /* set to preserve access and modification times on annotated message */
30    
31  int  int
32  annotate (char *file, char *comp, char *text, int inplace, int datesw, int delete, int append)  annotate (char *file, char *comp, char *text, int inplace, int datesw, int delete, int append)
33  {  {
34      int i, fd;      int                 i, fd;
35        struct utimbuf      b;
36        struct stat         s;
37    
38      /* open and lock the file to be annotated */      /* open and lock the file to be annotated */
39      if ((fd = lkopen (file, O_RDWR, 0)) == NOTOK) {      if ((fd = lkopen (file, O_RDWR, 0)) == NOTOK) {
# Line 39  annotate (char *file, char *comp, char * Line 48  annotate (char *file, char *comp, char *
48          return 1;          return 1;
49      }      }
50    
51        if (stat(file, &s) == -1) {
52            advise("can't get access and modification times for %s", file);
53            preserve_actime_and_modtime = 0;
54        }
55    
56        b.actime = s.st_atime;
57        b.modtime = s.st_mtime;
58    
59      i = annosbr (fd, file, comp, text, inplace, datesw, delete, append);      i = annosbr (fd, file, comp, text, inplace, datesw, delete, append);
60    
61        if (preserve_actime_and_modtime && utime(file, &b) == -1)
62            advise("can't set access and modification times for %s", file);
63    
64      lkclose (fd, file);      lkclose (fd, file);
65      return i;      return i;
66  }  }
# Line 138  annolist(char *file, char *comp, char *t Line 159  annolist(char *file, char *comp, char *t
159      return;      return;
160  }  }
161    
162    /*
163     *      Set the preserve-times flag.  This hack eliminates the need for an additional argument to annotate().
164     */
165    
166    void
167    annopreserve(int preserve)
168    {
169            preserve_actime_and_modtime = preserve;
170            return;
171    }
172    
173  static int  static int
174  annosbr (int fd, char *file, char *comp, char *text, int inplace, int datesw, int delete, int append)  annosbr (int fd, char *file, char *comp, char *text, int inplace, int datesw, int delete, int append)
# Line 173  annosbr (int fd, char *file, char *comp, Line 204  annosbr (int fd, char *file, char *comp,
204       *  as they're read in.  This buffer is grown as needed later.       *  as they're read in.  This buffer is grown as needed later.
205       */       */
206    
207      if (delete >= 0 || append != 0) {      if (delete >= -1 || append != 0) {
208          if ((fp = fdopen(fd, "r")) == (FILE *)0)          if ((fp = fdopen(fd, "r")) == (FILE *)0)
209              adios(NULL, "unable to fdopen file.");              adios(NULL, "unable to fdopen file.");
210    
# Line 183  annosbr (int fd, char *file, char *comp, Line 214  annosbr (int fd, char *file, char *comp,
214    
215      /*      /*
216       *  We're trying to delete a header field (annotation )if the delete flag is       *  We're trying to delete a header field (annotation )if the delete flag is
217       *  non-negative.  A  value greater than zero means that we're deleting the       *  not -2 or less.  A  value greater than zero means that we're deleting the
218       *  nth header field that matches the field (component) name.  A value of       *  nth header field that matches the field (component) name.  A value of
219       *  zero means that we're deleting the first field in which both the field       *  zero means that we're deleting the first field in which both the field
220       *  name matches the component name and the field body matches the text.       *  name matches the component name and the field body matches the text.
# Line 192  annosbr (int fd, char *file, char *comp, Line 223  annosbr (int fd, char *file, char *comp,
223       *  the last slash.  This allows matching of both absolute and relative path       *  the last slash.  This allows matching of both absolute and relative path
224       *  names.  This is because this functionality was added to support attachments.       *  names.  This is because this functionality was added to support attachments.
225       *  It might be worth having a separate flag to indicate path name matching to       *  It might be worth having a separate flag to indicate path name matching to
226       *  make it more general.       *  make it more general.  A value of -1 means to delete all matching fields.
227       */       */
228    
229      if (delete >= 0) {      if (delete >= -1) {
230          /*          /*
231           *  Get the length of the field name since we use it often.           *  Get the length of the field name since we use it often.
232           */           */
# Line 234  annosbr (int fd, char *file, char *comp, Line 265  annosbr (int fd, char *file, char *comp,
265                  if (++n >= field_size - 1) {                  if (++n >= field_size - 1) {
266                      if ((field = (char *)realloc((void *)field, field_size *= 2)) == (char *)0)                      if ((field = (char *)realloc((void *)field, field_size *= 2)) == (char *)0)
267                          adios(NULL, "can't grow field buffer.");                          adios(NULL, "can't grow field buffer.");
268                                        
269                      cp = field + n - 1;                      cp = field + n - 1;
270                  }                  }
271              }              }
# Line 260  annosbr (int fd, char *file, char *comp, Line 291  annosbr (int fd, char *file, char *comp,
291               *      field, the text does not begin with a / meaning that we're looking for the               *      field, the text does not begin with a / meaning that we're looking for the
292               *      last path name component, and the last path name component matches the text.               *      last path name component, and the last path name component matches the text.
293               *               *
294               *   o  The delete flag is non-zero meaning that we're going to delete the nth field               *   o  The delete flag is positive meaning that we're going to delete the nth field
295               *      with a matching field name, and this is the nth matching field name.               *      with a matching field name, and this is the nth matching field name.
296                 *
297                 *   o  The delete flag is -1 meaning that we're going to delete all fields with a
298                 *      matching field name.
299               */               */
300    
301              if (strncasecmp(field, comp, length) == 0 && field[length] == ':') {              if (strncasecmp(field, comp, length) == 0 && field[length] == ':') {
# Line 285  annosbr (int fd, char *file, char *comp, Line 319  annosbr (int fd, char *file, char *comp,
319                      }                      }
320                  }                  }
321    
322                    else if (delete == -1)
323                            continue;
324    
325                  else if (++count == delete)                  else if (++count == delete)
326                      break;                      break;
327              }              }
# Line 308  annosbr (int fd, char *file, char *comp, Line 345  annosbr (int fd, char *file, char *comp,
345      else {      else {
346          /*          /*
347           *  Find the end of the headers before adding the annotations if we're           *  Find the end of the headers before adding the annotations if we're
348           *  appending instead of the default prepending.           *  appending instead of the default prepending.  A special check for
349             *  no headers is needed if appending.
350           */           */
351    
352          if (append) {          if (append) {
# Line 317  annosbr (int fd, char *file, char *comp, Line 355  annosbr (int fd, char *file, char *comp,
355               *  reach the end of the headers.               *  reach the end of the headers.
356               */               */
357    
358              while ((c = getc(fp)) != EOF) {              if ((c = getc(fp)) == '\n')
359                  (void)putc(c, tmp);                  rewind(fp);
360    
361                  if (c == '\n') {              else {
362                      (void)ungetc(c = getc(fp), fp);                  (void)putc(c, tmp);
363    
364                      if (c == '\n' || c == '-')                  while ((c = getc(fp)) != EOF) {
365                          break;                      (void)putc(c, tmp);
366    
367                        if (c == '\n') {
368                            (void)ungetc(c = getc(fp), fp);
369    
370                            if (c == '\n' || c == '-')
371                                break;
372                        }
373                  }                  }
374              }              }
375          }          }
# Line 354  annosbr (int fd, char *file, char *comp, Line 399  annosbr (int fd, char *file, char *comp,
399       *  copying routine uses the descriptor, not the pointer.       *  copying routine uses the descriptor, not the pointer.
400       */       */
401    
402      if (append || delete >= 0) {      if (append || delete >= -1) {
403          if (lseek(fd, (off_t)ftell(fp), SEEK_SET) == (off_t)-1)          if (lseek(fd, (off_t)ftell(fp), SEEK_SET) == (off_t)-1)
404              adios(NULL, "can't seek.");              adios(NULL, "can't seek.");
405      }      }
# Line 373  annosbr (int fd, char *file, char *comp, Line 418  annosbr (int fd, char *file, char *comp,
418           *  so the file has to be truncated or it will contain garbage.           *  so the file has to be truncated or it will contain garbage.
419           */           */
420    
421          if (delete >= 0 && ftruncate(fd, 0) == -1)          if (delete >= -1 && ftruncate(fd, 0) == -1)
422              adios(tmpfil, "unable to truncate.");              adios(tmpfil, "unable to truncate.");
423    
424          cpydata (tmpfd, fd, tmpfil, file);          cpydata (tmpfd, fd, tmpfil, file);
# Line 405  annosbr (int fd, char *file, char *comp, Line 450  annosbr (int fd, char *file, char *comp,
450       *  lkclose() fail, but that failure is ignored so it's not a problem.       *  lkclose() fail, but that failure is ignored so it's not a problem.
451       */       */
452    
453      if (delete >= 0)      if (delete >= -1)
454          (void)fclose(fp);          (void)fclose(fp);
455    
456      return 0;      return 0;

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26