Annotation of 43BSD/contrib/emacs/etc/movemail.c, revision 1.1.1.1

1.1       root        1: /* movemail foo bar -- move file foo to file bar,
                      2:    locking file foo the way /bin/mail respects.
                      3:    Copyright (C) 1985 Richard M. Stallman.
                      4: 
                      5: This file is part of GNU Emacs.
                      6: 
                      7: GNU Emacs is distributed in the hope that it will be useful,
                      8: but without any warranty.  No author or distributor
                      9: accepts responsibility to anyone for the consequences of using it
                     10: or for whether it serves any particular purpose or works at all,
                     11: unless he says so in writing.
                     12: 
                     13: Everyone is granted permission to copy, modify and redistribute
                     14: GNU Emacs, but only under the conditions described in the
                     15: document "GNU Emacs copying permission notice".   An exact copy
                     16: of the document is supposed to have been given to you along with
                     17: GNU Emacs so that you can know how you may redistribute it all.
                     18: It should be in a file named COPYING.  Among other things, the
                     19: copyright notice and this notice must be preserved on all copies.  */
                     20: 
                     21: #include <sys/types.h>
                     22: #include <sys/stat.h>
                     23: #include <sys/file.h>
                     24: #define NO_SHORTNAMES   /* Tell config not to load remap.h */
                     25: #include "../src/config.h"
                     26: 
                     27: #ifdef USG
                     28: #include <fcntl.h>
                     29: #endif /* USG */
                     30: 
                     31: /* Cancel substitutions made by config.h for Emacs.  */
                     32: #undef open
                     33: #undef read
                     34: #undef write
                     35: 
                     36: char *concat ();
                     37: 
                     38: main (argc, argv)
                     39:      int argc;
                     40:      char **argv;
                     41: {
                     42:   char *inname, *outname;
                     43:   int indesc, outdesc;
                     44:   char buf[1024];
                     45:   int nread;
                     46: 
                     47: #ifndef MAIL_USE_FLOCK
                     48:   struct stat st;
                     49:   long now;
                     50:   int tem;
                     51:   char *lockname, *p;
                     52:   char tempname[40];
                     53:   int desc;
                     54: #endif /* not MAIL_USE_FLOCK */
                     55: 
                     56:   if (argc < 3)
                     57:     fatal ("two arguments required");
                     58: 
                     59:   inname = argv[1];
                     60:   outname = argv[2];
                     61: 
                     62: #ifndef MAIL_USE_FLOCK
                     63:   /* Use a lock file named /usr/spool/mail/$USER.lock:
                     64:      If it exists, the mail file is locked.  */
                     65:   lockname = concat (inname, ".lock", "");
                     66:   strcpy (tempname, inname);
                     67:   p = tempname + strlen (tempname);
                     68:   while (p != tempname && p[-1] != '/')
                     69:     p--;
                     70:   *p = 0;
                     71:   strcpy (p, "EXXXXXX");
                     72:   mktemp (tempname);
                     73:   unlink (tempname);
                     74: 
                     75:   while (1)
                     76:     {
                     77:       /* Create the lock file, but not under the lock file name.  */
                     78:       /* Give up if cannot do that.  */
                     79:       desc = open (tempname, O_WRONLY | O_CREAT, 0666);
                     80:       if (desc < 0)
                     81:        exit (1);
                     82:       close (desc);
                     83: 
                     84:       tem = link (tempname, lockname);
                     85:       unlink (tempname);
                     86:       if (tem >= 0)
                     87:        break;
                     88:       sleep (1);
                     89: 
                     90:       /* If lock file is a minute old, unlock it.  */
                     91:       if (stat (lockname, &st) >= 0)
                     92:        {
                     93:          now = time (0);
                     94:          if (st.st_ctime < now - 60)
                     95:            unlink (lockname);
                     96:        }
                     97:     }
                     98: #endif /* not MAIL_USE_FLOCK */
                     99: 
                    100: #ifdef MAIL_USE_FLOCK
                    101:   indesc = open (inname, O_RDWR);
                    102: #else /* if not MAIL_USE_FLOCK */
                    103:   indesc = open (inname, O_RDONLY);
                    104: #endif /* not MAIL_USE_FLOCK */
                    105:   if (indesc < 0)
                    106:     pfatal_with_name (inname);
                    107: #ifdef BSD
                    108:   /* In case movemail is setuid to root, make sure the user can
                    109:      read the output file.  */
                    110:   /* This is desirable for all systems
                    111:      but I don't want to assume all have the umask system call */
                    112:   umask (umask (0) & 0333);
                    113: #endif /* BSD */
                    114:   outdesc = open (outname, O_WRONLY | O_CREAT | O_EXCL, 0666);
                    115:   if (outdesc < 0)
                    116:     pfatal_with_name (outname);
                    117: #ifdef MAIL_USE_FLOCK
                    118:   (void) flock (indesc, LOCK_EX);
                    119: #endif /* MAIL_USE_FLOCK */
                    120: 
                    121:   while (1)
                    122:     {
                    123:       nread = read (indesc, buf, sizeof buf);
                    124:       if (nread != write (outdesc, buf, nread))
                    125:        fatal ("error writing to %s", outname);
                    126:       if (nread < sizeof buf)
                    127:        break;
                    128:     }
                    129: 
                    130: #ifdef MAIL_USE_FLOCK
                    131:   (void) ftruncate (indesc, 0L);
                    132: #endif /* MAIL_USE_FLOCK */
                    133:   close (indesc);
                    134:   close (outdesc);
                    135: #ifndef MAIL_USE_FLOCK
                    136:   unlink (inname);
                    137:   unlink (lockname);
                    138: #endif /* not MAIL_USE_FLOCK */
                    139:   exit (0);
                    140: }
                    141: 
                    142: /* Print error message and exit.  */
                    143: 
                    144: fatal (s1, s2)
                    145:      char *s1, *s2;
                    146: {
                    147:   error (s1, s2);
                    148:   exit (1);
                    149: }
                    150: 
                    151: /* Print error message.  `s1' is printf control string, `s2' is arg for it. */
                    152: 
                    153: error (s1, s2)
                    154:      char *s1, *s2;
                    155: {
                    156:   printf ("movemail: ");
                    157:   printf (s1, s2);
                    158:   printf ("\n");
                    159: }
                    160: 
                    161: pfatal_with_name (name)
                    162:      char *name;
                    163: {
                    164:   extern int errno, sys_nerr;
                    165:   extern char *sys_errlist[];
                    166:   char *s;
                    167: 
                    168:   if (errno < sys_nerr)
                    169:     s = concat ("", sys_errlist[errno], " for %s");
                    170:   else
                    171:     s = "cannot open %s";
                    172:   fatal (s, name);
                    173: }
                    174: 
                    175: /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3.  */
                    176: 
                    177: char *
                    178: concat (s1, s2, s3)
                    179:      char *s1, *s2, *s3;
                    180: {
                    181:   int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
                    182:   char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
                    183: 
                    184:   strcpy (result, s1);
                    185:   strcpy (result + len1, s2);
                    186:   strcpy (result + len1 + len2, s3);
                    187:   *(result + len1 + len2 + len3) = 0;
                    188: 
                    189:   return result;
                    190: }
                    191: 
                    192: /* Like malloc but get fatal error if memory is exhausted.  */
                    193: 
                    194: int
                    195: xmalloc (size)
                    196:      int size;
                    197: {
                    198:   int result = malloc (size);
                    199:   if (!result)
                    200:     fatal ("virtual memory exhausted", 0);
                    201:   return result;
                    202: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.