home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / b / bmh02src.zip / RMM.C < prev    next >
C/C++ Source or Header  |  1992-08-16  |  6KB  |  212 lines

  1. /*
  2.    rmm.c : Copyright Paul Healy, EI9GL, 1992.
  3.  
  4.    911227 : Added this header
  5.    920708 : Version 0.1
  6.    920711 : Profiled and optimised a bit.
  7.             The program spends at least 60% of its time scanning for the
  8.             next message. About the only thing that could be done is to
  9.             block copy the rest of the file after the last message to be
  10.             deleted is found - this is a special case optimisiation which
  11.             will not be any good when a message is to be deleted at or towards
  12.             the end of the mail file.
  13.    920808 : Changed selection for new current message after a message(s) is
  14.             deleted.
  15. */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <ctype.h>
  20. #include <sys/stat.h>
  21. #include <io.h>
  22. #include <alloc.h>
  23. #include "buffer.h"
  24. #include "rc.h"
  25. #include "lock.h"
  26. #include "misc.h"
  27. #include "help.h"
  28. #include "current.h"
  29. #include "name.h"
  30.  
  31. #ifdef BMH
  32. #define main rmm_main
  33. #endif
  34.  
  35. #define check(condition, msg, file) if (condition) { \
  36.  fprintf(stderr, msg, file); \
  37.  unlink(new); \
  38.  if (locked) bm_unlock(lock); \
  39.  return -1; \
  40. }
  41.  
  42. static int
  43. update(char *lock, char *new, long size)
  44. {
  45.    struct stat statbuf;
  46.    char txt[256], old[256];
  47.    int locked = 0;
  48.  
  49.    sprintf(old, "%s.old", lock);
  50.    sprintf(txt, "%s%s", lock, EXT);
  51.  
  52.    check(bm_lock(lock) != 0, "rmm: can't lock %s\n", txt);
  53.    locked = 1;
  54.    check(stat(txt, &statbuf) == -1, "rmm: can't stat %s\n", txt);
  55.    check(statbuf.st_size != size, "rmm: %s has been changed\n", txt);
  56.    check((access(old, 0)==0) && (unlink(old) == -1), "rmm: can't unlink %s\n", old);
  57.    check(rename(txt, old) == -1, "rmm: can't rename %s to make backup\n", txt);
  58.    check(rename(new, txt) == -1, "rmm: can't rename %s to make new mailfile\n", new);
  59.    check(bm_unlock(lock) != 0, "rmm: can't unlock %s\n", txt);
  60.  
  61.    return unlink(new);
  62. }
  63. #undef check
  64.  
  65. #ifdef notdef
  66.       while ( (p<end) && (*p!='F') )
  67.          if (putc(*p++, fp) == EOF) {
  68.             fprintf(stderr, "rmm: can't to write temporary file\n");
  69.             fclose(fp);
  70.             return -1;
  71.             }
  72. #endif
  73.  
  74. static int   
  75. delmsgs(char *p, char *end, int argc, char *argv[], char *folder, int default_msg)
  76. {
  77.    char s[2048], new[256], basename[256], *result, *start;
  78.    int msg = 0, num;
  79.    FILE *fp;
  80.    long fsize = filesize();
  81.  
  82.    sprintf(basename, "%s/%s", getrc(maildir), folder);
  83.    sprintf(new, "%s.new", basename);
  84.  
  85.    if ((fp=fopen(new, "wb")) == NULL) {
  86.       fprintf(stderr, "rmm: can't open %s\n", new);
  87.       return -1;
  88.       }
  89.    if (setvbuf(fp, NULL, _IOFBF, 4096) != 0) {
  90.       fprintf(stderr,"rmm: warning can't buffer %s\n(tried 4096, coreleft=%u)\n", new, coreleft());
  91.       if (setvbuf(fp, NULL, _IOFBF, 1024) != 0)
  92.          fprintf(stderr,"rmm: warning can't buffer %s\n(tried 1024, coreleft=%u)\n", new, coreleft());
  93.       }
  94.  
  95.    while (1) {
  96.       start = p;
  97.       {
  98.          register char *rp = p;
  99.  
  100.          /*
  101.           * 60 to 70% of this programs life is spent executing the
  102.           * next 2 lines of code according to the profiler.
  103.           */
  104.  
  105.          while ( *rp != 'F' )
  106.             rp++;
  107.  
  108.          p = rp;
  109.       }
  110.       if (p != start) {
  111.          num = p - start;
  112.          if (fwrite(start, sizeof(char), num, fp) != num) {
  113.             fprintf(stderr, "rmm: can't to write temporary file\n");
  114.             fclose(fp);
  115.             unlink(new);
  116.             return -1;
  117.             }
  118.          }
  119.  
  120.       if ( (p==end) && (refill(&p, &end) != 0) )
  121.          break;
  122.       else {                              /* may have found a From */
  123.          if (*(p-1) != '\n') {
  124.             if (putc(*p++, fp) != EOF)
  125.                continue; /* at while 1 */
  126.             fprintf(stderr, "rmm: can't write temporary file\n");
  127.             fclose(fp);
  128.             return -1;
  129.             }
  130.  
  131.          result = getstring(&p, &end, s, sizeof(s));
  132.  
  133.          if (strncmp(s, "From ", 5) == 0) {
  134.             msg++;
  135. /*
  136.             printf("rmm: considering %s\n", s);
  137. */
  138.             while ((result != NULL ) &&
  139.                (wanted(msg, argc, argv, default_msg) == 1) )
  140.                while ((result=getstring(&p, &end, s, sizeof(s))) != NULL)
  141.                   if (strncmp(s, "From ", 5) == 0) {
  142.                      msg++;
  143.                      break;
  144.                      }
  145.  
  146.              if (result != NULL) {
  147.                fputs(s, fp); /* unwanted From line */
  148.                fputs("\r\n", fp);
  149.                }
  150.  
  151.             }
  152.          else {
  153.             fputs(s, fp);    /* string with 'F' in it */
  154.             fputs("\r\n", fp);
  155.             }
  156.          }
  157.       }  /* while 1 */
  158.  
  159.    fclose(fp);
  160.    return update(basename, new, fsize);
  161. }
  162.  
  163. /*
  164.  * remove a zero length file
  165.  */
  166. static void
  167. checkempty(char *folder)
  168. {
  169. /*
  170.    printf("%s\n%s\n%s\n%s\n", getnm(BaseName), getnm(TxtName), getnm(NewName), getnm(OldName));
  171. */
  172.    if (bm_lock(getnm(BaseName)) == 0) {
  173.       struct stat statbuf;
  174.  
  175.       if ( (stat(getnm(TxtName), &statbuf) == 0) && (statbuf.st_size == 0))
  176.          (void) unlink(getnm(TxtName));
  177.       if (bm_unlock(getnm(BaseName)) != 0)
  178.          fprintf(stderr, "rmm: warning %s may have been left locked\n", getnm(TxtName));
  179.       }
  180. }
  181.  
  182. int
  183. main(int argc, char *argv[])
  184. {
  185.    char *p, *end, *s;
  186.    int msg;
  187.  
  188.    dohelp(argc, argv, "rmm [+folder] <msg 1> ... <msg n>");
  189.  
  190.    if (loadconfig()==-1) /* don't use setupbm, as we don't need */
  191.       return -1;         /* to buffer stdout */
  192.  
  193.    if (getcurrent(argc, argv, &s, &msg) == -1)
  194.       return -1;
  195.    
  196.    if (loadmail("rmm", s, &p, &end) == -1)
  197.       return -1;
  198.  
  199.    delmsgs(p, end, argc, argv, s, msg);
  200.  
  201.    checkempty(s);
  202.  
  203.    /*
  204.     * The previous message to the first deleted message becomes the
  205.     * new current message
  206.     */
  207.    msg--;
  208.    currentmsg(&msg);
  209.  
  210.    return 0;
  211. }
  212.