|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.