home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / AP / JED / JED097-1.TAR / jed / src / getmail.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-12  |  2.3 KB  |  125 lines

  1. /* This routine is written in C to avoid possible race condition
  2.    when moving mail from a maildir. */
  3.  
  4. #include <stdio.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <errno.h>
  8. #include <sys/file.h>
  9. #include <time.h>
  10. #ifdef SYSV
  11. #include <sys/fcntl.h>
  12. #endif
  13.  
  14. #include "config.h"
  15. static char *Program_Name;
  16.  
  17. /* A lock file is just file.lock */
  18.  
  19. extern void exit_error(char *, int);
  20.  
  21. void usage()
  22. {
  23.    fprintf(stderr, "%s: usage: %s infile outfile\n", Program_Name, Program_Name);
  24.    exit (-1);
  25. }
  26.  
  27. char *Lock_Filep;
  28. void make_lock_name(char *file, char *lockfile)
  29. {
  30.    sprintf(lockfile, "%s.lock", file);
  31.    Lock_Filep = lockfile;
  32. }
  33.  
  34.  
  35. int lock_mail_file(char *f, int attempts)
  36. {
  37.    struct stat s;
  38.    char buf[80];
  39.    int fd;
  40.       
  41.    while (attempts-- > 0)
  42.      {
  43.     if (stat(f, &s) < 0)
  44.       {
  45.          if (errno != ENOENT) exit_error("stat failed.", 0);
  46.          fd = open(f, O_EXCL | O_CREAT, 0666);
  47.          if (fd >= 0) 
  48.            {
  49.           sprintf(buf, "%d", getpid());
  50.           write(fd, buf, strlen(buf));
  51.           close(fd);
  52.           return (fd);
  53.            }
  54.       }
  55.     else if (time((time_t *) NULL) - s.st_ctime > 60) (void) unlink(f);
  56.     
  57.     sleep(1);
  58.      }
  59.    return (-1);
  60. }
  61.  
  62. void mv_mail(char *from, char *to)
  63. {
  64.    char buf[8192];
  65.    int fdfrom, fdto;
  66.    int n;
  67.    
  68.    if ((fdfrom = open(from, O_RDONLY, 0666)) < 0) exit_error("Unable to open input file.", 1);
  69.    if ((fdto = open(to, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) exit_error("Unable to create output file.", 1);
  70.    while ((n = read(fdfrom, buf, sizeof(buf))) > 0)
  71.      {
  72.     if (n != write(fdto, buf, n)) 
  73.       {         
  74.          exit_error("write failed.", 1);
  75.       }
  76.      }
  77.    
  78.    close(fdto);
  79.    close(fdfrom);
  80.    if (unlink(from))
  81.      {
  82.     if ((fdfrom = open(from, O_WRONLY | O_CREAT | O_TRUNC, 0600)) >= 0) close(fdfrom);
  83.      }
  84. }
  85.  
  86.  
  87. void unlock_mail_file(char *f)
  88. {
  89.    unlink(f);
  90. }
  91.  
  92. void exit_error(char *s, int l)
  93. {
  94.    fprintf(stderr, "%s: %s\n", Program_Name, s);
  95.    if (l) unlock_mail_file(Lock_Filep);
  96.    exit(-1);
  97. }
  98.  
  99.  
  100.    
  101. int main(int argc, char **argv)
  102. {
  103.    char *in, *out;
  104.    char lockfile[256];
  105.    
  106.    Program_Name = argv[0];
  107.    if (argc != 3) usage();
  108.    in = argv[1];
  109.    out = argv[2];
  110.    
  111.    make_lock_name(in, lockfile);
  112.    
  113.    if (lock_mail_file (lockfile, 60) < 0)
  114.      {
  115.     exit_error("Unable to lock file.", 0);
  116.      }
  117.    
  118.    mv_mail(in, out);
  119.    unlock_mail_file(lockfile);
  120.    return(0);
  121. }
  122.  
  123.    
  124.    
  125.