|
|
1.1 ! root 1: # ! 2: ! 3: #include "rcv.h" ! 4: #include <sys/stat.h> ! 5: ! 6: /* ! 7: * Mail -- a mail program ! 8: * ! 9: * More user commands. ! 10: */ ! 11: ! 12: /* ! 13: * If any arguments were given, go to the next applicable argument ! 14: * following dot, otherwise, go to the next applicable message. ! 15: * If given as first command with no arguments, print first message. ! 16: */ ! 17: ! 18: next(msgvec) ! 19: int *msgvec; ! 20: { ! 21: register struct message *mp; ! 22: register int *ip, *ip2; ! 23: int list[2], mdot; ! 24: ! 25: if (*msgvec != NULL) { ! 26: ! 27: /* ! 28: * If some messages were supplied, find the ! 29: * first applicable one following dot using ! 30: * wrap around. ! 31: */ ! 32: ! 33: mdot = dot - &message[0] + 1; ! 34: for (ip = msgvec; *ip != NULL; ip++) ! 35: if (*ip > mdot) ! 36: break; ! 37: if (*ip == NULL) ! 38: ip = msgvec; ! 39: ip2 = ip; ! 40: do { ! 41: if (*ip2 != NULL) ! 42: ip2++; ! 43: if (*ip2 == NULL) ! 44: ip2 = msgvec; ! 45: mp = &message[*ip2 - 1]; ! 46: if ((mp->m_flag & (MDELETED|MSAVED)) == 0) { ! 47: dot = mp; ! 48: goto hitit; ! 49: } ! 50: } while (ip2 != ip); ! 51: printf("No messages applicable\n"); ! 52: return(1); ! 53: } ! 54: ! 55: /* ! 56: * If this is the first command, select message 1. ! 57: * Note that this must exist for us to get here at all. ! 58: */ ! 59: ! 60: if (!sawcom) { ! 61: dot = &message[0]; ! 62: goto hitit; ! 63: } ! 64: ! 65: /* ! 66: * Just find the next good message after dot, no ! 67: * wraparound. ! 68: */ ! 69: ! 70: for (mp = dot+1; mp < &message[msgCount]; mp++) ! 71: if ((mp->m_flag & (MDELETED|MSAVED)) == 0) ! 72: break; ! 73: if (mp >= &message[msgCount]) { ! 74: printf("At EOF\n"); ! 75: return(0); ! 76: } ! 77: dot = mp; ! 78: hitit: ! 79: /* ! 80: * Print dot. ! 81: */ ! 82: ! 83: list[0] = dot - &message[0] + 1; ! 84: list[1] = NULL; ! 85: return(type(list)); ! 86: } ! 87: ! 88: /* ! 89: * Save the indicated messages at the end of the passed file name. ! 90: */ ! 91: ! 92: save(str) ! 93: char str[]; ! 94: { ! 95: register int *ip, mesg; ! 96: register struct message *mp; ! 97: char *file; ! 98: int f, *msgvec, lc, cc, t; ! 99: FILE *obuf; ! 100: ! 101: msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); ! 102: if ((file = snarf(str, &f)) == NOSTR) ! 103: return(1); ! 104: if (!f) { ! 105: *msgvec = first(0, MMNORM); ! 106: if (*msgvec == NULL) { ! 107: printf("No messages to save.\n"); ! 108: return(1); ! 109: } ! 110: msgvec[1] = NULL; ! 111: } ! 112: if (f && getmsglist(str, msgvec, 0) < 0) ! 113: return(1); ! 114: if ((file = expand(file)) == NOSTR) ! 115: return(1); ! 116: printf("\"%s\" ", file); ! 117: flush(); ! 118: if ((obuf = fopen(file, "a")) == NULL) { ! 119: perror(NOSTR); ! 120: return(1); ! 121: } ! 122: cc = lc = 0; ! 123: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { ! 124: mesg = *ip; ! 125: touch(mesg); ! 126: mp = &message[mesg-1]; ! 127: if ((t = send(mp, obuf)) < 0) { ! 128: perror(file); ! 129: fclose(obuf); ! 130: return(1); ! 131: } ! 132: lc += t; ! 133: cc += msize(mp); ! 134: mp->m_flag |= MSAVED; ! 135: } ! 136: fflush(obuf); ! 137: if (ferror(obuf)) ! 138: perror(file); ! 139: fclose(obuf); ! 140: printf("%d/%d\n", lc, cc); ! 141: return(0); ! 142: } ! 143: ! 144: /* ! 145: * Write the indicated messages at the end of the passed ! 146: * file name, minus header and trailing blank line. ! 147: */ ! 148: ! 149: swrite(str) ! 150: char str[]; ! 151: { ! 152: register int *ip, mesg; ! 153: register struct message *mp; ! 154: register char *file; ! 155: char linebuf[BUFSIZ]; ! 156: int f, *msgvec, lc, cc, t; ! 157: FILE *obuf, *mesf; ! 158: ! 159: msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); ! 160: if ((file = snarf(str, &f)) == NOSTR) ! 161: return(1); ! 162: if ((file = expand(file)) == NOSTR) ! 163: return(1); ! 164: if (!f) { ! 165: *msgvec = first(0, MMNORM); ! 166: if (*msgvec == NULL) { ! 167: printf("No messages to write.\n"); ! 168: return(1); ! 169: } ! 170: msgvec[1] = NULL; ! 171: } ! 172: if (f && getmsglist(str, msgvec, 0) < 0) ! 173: return(1); ! 174: printf("\"%s\" ", file); ! 175: flush(); ! 176: if ((obuf = fopen(file, "a")) == NULL) { ! 177: perror(NOSTR); ! 178: return(1); ! 179: } ! 180: cc = lc = 0; ! 181: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { ! 182: mesg = *ip; ! 183: touch(mesg); ! 184: mp = &message[mesg-1]; ! 185: mesf = setinput(mp); ! 186: t = mp->m_lines - 2; ! 187: readline(mesf, linebuf); ! 188: while (t-- > 0) { ! 189: fgets(linebuf, BUFSIZ, mesf); ! 190: fputs(linebuf, obuf); ! 191: cc += strlen(linebuf); ! 192: } ! 193: lc += mp->m_lines - 2; ! 194: mp->m_flag |= MSAVED; ! 195: } ! 196: fflush(obuf); ! 197: if (ferror(obuf)) ! 198: perror(file); ! 199: fclose(obuf); ! 200: printf("%d/%d\n", lc, cc); ! 201: return(0); ! 202: } ! 203: ! 204: /* ! 205: * Snarf the file from the end of the command line and ! 206: * return a pointer to it. If there is no file attached, ! 207: * just return NOSTR. Put a null in front of the file ! 208: * name so that the message list processing won't see it, ! 209: * unless the file name is the only thing on the line, in ! 210: * which case, return 0 in the reference flag variable. ! 211: */ ! 212: ! 213: char * ! 214: snarf(linebuf, flag) ! 215: char linebuf[]; ! 216: int *flag; ! 217: { ! 218: register char *cp; ! 219: ! 220: *flag = 1; ! 221: cp = strlen(linebuf) + linebuf - 1; ! 222: ! 223: /* ! 224: * Strip away trailing blanks. ! 225: */ ! 226: ! 227: while (*cp == ' ' && cp > linebuf) ! 228: cp--; ! 229: *++cp = 0; ! 230: ! 231: /* ! 232: * Now search for the beginning of the file name. ! 233: */ ! 234: ! 235: while (cp > linebuf && !any(*cp, "\t ")) ! 236: cp--; ! 237: if (*cp == '\0') { ! 238: printf("No file specified.\n"); ! 239: return(NOSTR); ! 240: } ! 241: if (any(*cp, " \t")) ! 242: *cp++ = 0; ! 243: else ! 244: *flag = 0; ! 245: return(cp); ! 246: } ! 247: ! 248: /* ! 249: * Delete messages. ! 250: */ ! 251: ! 252: delete(msgvec) ! 253: int msgvec[]; ! 254: { ! 255: return(delm(msgvec)); ! 256: } ! 257: ! 258: /* ! 259: * Delete messages, then type the new dot. ! 260: */ ! 261: ! 262: deltype(msgvec) ! 263: int msgvec[]; ! 264: { ! 265: int list[2]; ! 266: ! 267: if (delm(msgvec) >= 0) { ! 268: list[0] = dot - &message[0]; ! 269: list[0]++; ! 270: touch(list[0]); ! 271: list[1] = NULL; ! 272: return(type(list)); ! 273: } ! 274: else { ! 275: printf("No more messages\n"); ! 276: return(0); ! 277: } ! 278: } ! 279: ! 280: /* ! 281: * Delete the indicated messages. ! 282: * Set dot to some nice place afterwards. ! 283: * Internal interface. ! 284: */ ! 285: ! 286: delm(msgvec) ! 287: int *msgvec; ! 288: { ! 289: register struct message *mp; ! 290: register *ip, mesg; ! 291: int last; ! 292: ! 293: last = NULL; ! 294: for (ip = msgvec; *ip != NULL; ip++) { ! 295: mesg = *ip; ! 296: touch(mesg); ! 297: mp = &message[mesg-1]; ! 298: mp->m_flag |= MDELETED; ! 299: mp->m_flag &= ~(MPRESERVE|MSAVED); ! 300: last = mesg; ! 301: } ! 302: if (last != NULL) { ! 303: dot = &message[last-1]; ! 304: last = first(0, MDELETED); ! 305: if (last != NULL) { ! 306: dot = &message[last-1]; ! 307: return(0); ! 308: } ! 309: else { ! 310: dot = &message[0]; ! 311: return(-1); ! 312: } ! 313: } ! 314: ! 315: /* ! 316: * Following can't happen -- it keeps lint happy ! 317: */ ! 318: ! 319: return(-1); ! 320: } ! 321: ! 322: /* ! 323: * Undelete the indicated messages. ! 324: */ ! 325: ! 326: undelete(msgvec) ! 327: int *msgvec; ! 328: { ! 329: register struct message *mp; ! 330: register *ip, mesg; ! 331: ! 332: for (ip = msgvec; ip-msgvec < msgCount; ip++) { ! 333: mesg = *ip; ! 334: if (mesg == 0) ! 335: return; ! 336: touch(mesg); ! 337: mp = &message[mesg-1]; ! 338: dot = mp; ! 339: mp->m_flag &= ~MDELETED; ! 340: } ! 341: } ! 342: ! 343: /* ! 344: * Interactively dump core on "core" ! 345: */ ! 346: ! 347: core() ! 348: { ! 349: register int pid; ! 350: int status; ! 351: ! 352: if ((pid = vfork()) == -1) { ! 353: perror("fork"); ! 354: return(1); ! 355: } ! 356: if (pid == 0) { ! 357: abort(); ! 358: _exit(1); ! 359: } ! 360: printf("Okie dokie"); ! 361: fflush(stdout); ! 362: while (wait(&status) != pid) ! 363: ; ! 364: if (status & 0200) ! 365: printf(" -- Core dumped\n"); ! 366: else ! 367: printf("\n"); ! 368: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.