Annotation of 43BSD/contrib/emacs/etc/movemail.c, revision 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.