|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)cmd2.c 2.11 (Berkeley) 8/11/83"; ! 3: #endif ! 4: ! 5: #include "rcv.h" ! 6: #include <sys/stat.h> ! 7: ! 8: /* ! 9: * Mail -- a mail program ! 10: * ! 11: * More user commands. ! 12: */ ! 13: ! 14: /* ! 15: * If any arguments were given, go to the next applicable argument ! 16: * following dot, otherwise, go to the next applicable message. ! 17: * If given as first command with no arguments, print first message. ! 18: */ ! 19: ! 20: next(msgvec) ! 21: int *msgvec; ! 22: { ! 23: register struct message *mp; ! 24: register int *ip, *ip2; ! 25: int list[2], mdot; ! 26: ! 27: if (*msgvec != NULL) { ! 28: ! 29: /* ! 30: * If some messages were supplied, find the ! 31: * first applicable one following dot using ! 32: * wrap around. ! 33: */ ! 34: ! 35: mdot = dot - &message[0] + 1; ! 36: ! 37: /* ! 38: * Find the first message in the supplied ! 39: * message list which follows dot. ! 40: */ ! 41: ! 42: for (ip = msgvec; *ip != NULL; ip++) ! 43: if (*ip > mdot) ! 44: break; ! 45: if (*ip == NULL) ! 46: ip = msgvec; ! 47: ip2 = ip; ! 48: do { ! 49: mp = &message[*ip2 - 1]; ! 50: if ((mp->m_flag & MDELETED) == 0) { ! 51: dot = mp; ! 52: goto hitit; ! 53: } ! 54: if (*ip2 != NULL) ! 55: ip2++; ! 56: if (*ip2 == NULL) ! 57: ip2 = msgvec; ! 58: } while (ip2 != ip); ! 59: printf("No messages applicable\n"); ! 60: return(1); ! 61: } ! 62: ! 63: /* ! 64: * If this is the first command, select message 1. ! 65: * Note that this must exist for us to get here at all. ! 66: */ ! 67: ! 68: if (!sawcom) ! 69: goto hitit; ! 70: ! 71: /* ! 72: * Just find the next good message after dot, no ! 73: * wraparound. ! 74: */ ! 75: ! 76: for (mp = dot+1; mp < &message[msgCount]; mp++) ! 77: if ((mp->m_flag & (MDELETED|MSAVED)) == 0) ! 78: break; ! 79: if (mp >= &message[msgCount]) { ! 80: printf("At EOF\n"); ! 81: return(0); ! 82: } ! 83: dot = mp; ! 84: hitit: ! 85: /* ! 86: * Print dot. ! 87: */ ! 88: ! 89: list[0] = dot - &message[0] + 1; ! 90: list[1] = NULL; ! 91: return(type(list)); ! 92: } ! 93: ! 94: /* ! 95: * Save a message in a file. Mark the message as saved ! 96: * so we can discard when the user quits. ! 97: */ ! 98: save(str) ! 99: char str[]; ! 100: { ! 101: ! 102: return(save1(str, 1)); ! 103: } ! 104: ! 105: /* ! 106: * Copy a message to a file without affected its saved-ness ! 107: */ ! 108: copycmd(str) ! 109: char str[]; ! 110: { ! 111: ! 112: return(save1(str, 0)); ! 113: } ! 114: ! 115: /* ! 116: * Save/copy the indicated messages at the end of the passed file name. ! 117: * If mark is true, mark the message "saved." ! 118: */ ! 119: save1(str, mark) ! 120: char str[]; ! 121: { ! 122: register int *ip, mesg; ! 123: register struct message *mp; ! 124: char *file, *disp, *cmd; ! 125: int f, *msgvec, lc, t; ! 126: long cc; ! 127: FILE *obuf; ! 128: struct stat statb; ! 129: ! 130: cmd = mark ? "save" : "copy"; ! 131: msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); ! 132: if ((file = snarf(str, &f)) == NOSTR) ! 133: return(1); ! 134: if (!f) { ! 135: *msgvec = first(0, MMNORM); ! 136: if (*msgvec == NULL) { ! 137: printf("No messages to %s.\n", cmd); ! 138: return(1); ! 139: } ! 140: msgvec[1] = NULL; ! 141: } ! 142: if (f && getmsglist(str, msgvec, 0) < 0) ! 143: return(1); ! 144: if ((file = expand(file)) == NOSTR) ! 145: return(1); ! 146: printf("\"%s\" ", file); ! 147: flush(); ! 148: if (stat(file, &statb) >= 0) ! 149: disp = "[Appended]"; ! 150: else ! 151: disp = "[New file]"; ! 152: if ((obuf = fopen(file, "a")) == NULL) { ! 153: perror(NOSTR); ! 154: return(1); ! 155: } ! 156: cc = 0L; ! 157: lc = 0; ! 158: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { ! 159: mesg = *ip; ! 160: touch(mesg); ! 161: mp = &message[mesg-1]; ! 162: if ((t = send(mp, obuf, 0)) < 0) { ! 163: perror(file); ! 164: fclose(obuf); ! 165: return(1); ! 166: } ! 167: lc += t; ! 168: cc += mp->m_size; ! 169: if (mark) ! 170: mp->m_flag |= MSAVED; ! 171: } ! 172: fflush(obuf); ! 173: if (ferror(obuf)) ! 174: perror(file); ! 175: fclose(obuf); ! 176: printf("%s %d/%ld\n", disp, lc, cc); ! 177: return(0); ! 178: } ! 179: ! 180: /* ! 181: * Write the indicated messages at the end of the passed ! 182: * file name, minus header and trailing blank line. ! 183: */ ! 184: ! 185: swrite(str) ! 186: char str[]; ! 187: { ! 188: register int *ip, mesg; ! 189: register struct message *mp; ! 190: register char *file, *disp; ! 191: char linebuf[BUFSIZ]; ! 192: int f, *msgvec, lc, cc, t; ! 193: FILE *obuf, *mesf; ! 194: struct stat statb; ! 195: ! 196: msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); ! 197: if ((file = snarf(str, &f)) == NOSTR) ! 198: return(1); ! 199: if ((file = expand(file)) == NOSTR) ! 200: return(1); ! 201: if (!f) { ! 202: *msgvec = first(0, MMNORM); ! 203: if (*msgvec == NULL) { ! 204: printf("No messages to write.\n"); ! 205: return(1); ! 206: } ! 207: msgvec[1] = NULL; ! 208: } ! 209: if (f && getmsglist(str, msgvec, 0) < 0) ! 210: return(1); ! 211: printf("\"%s\" ", file); ! 212: flush(); ! 213: if (stat(file, &statb) >= 0) ! 214: disp = "[Appended]"; ! 215: else ! 216: disp = "[New file]"; ! 217: if ((obuf = fopen(file, "a")) == NULL) { ! 218: perror(NOSTR); ! 219: return(1); ! 220: } ! 221: cc = lc = 0; ! 222: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { ! 223: mesg = *ip; ! 224: touch(mesg); ! 225: mp = &message[mesg-1]; ! 226: mesf = setinput(mp); ! 227: t = mp->m_lines - 2; ! 228: readline(mesf, linebuf); ! 229: while (t-- > 0) { ! 230: fgets(linebuf, BUFSIZ, mesf); ! 231: fputs(linebuf, obuf); ! 232: cc += strlen(linebuf); ! 233: } ! 234: lc += mp->m_lines - 2; ! 235: mp->m_flag |= MSAVED; ! 236: } ! 237: fflush(obuf); ! 238: if (ferror(obuf)) ! 239: perror(file); ! 240: fclose(obuf); ! 241: printf("%s %d/%d\n", disp, lc, cc); ! 242: return(0); ! 243: } ! 244: ! 245: /* ! 246: * Snarf the file from the end of the command line and ! 247: * return a pointer to it. If there is no file attached, ! 248: * just return NOSTR. Put a null in front of the file ! 249: * name so that the message list processing won't see it, ! 250: * unless the file name is the only thing on the line, in ! 251: * which case, return 0 in the reference flag variable. ! 252: */ ! 253: ! 254: char * ! 255: snarf(linebuf, flag) ! 256: char linebuf[]; ! 257: int *flag; ! 258: { ! 259: register char *cp; ! 260: ! 261: *flag = 1; ! 262: cp = strlen(linebuf) + linebuf - 1; ! 263: ! 264: /* ! 265: * Strip away trailing blanks. ! 266: */ ! 267: ! 268: while (*cp == ' ' && cp > linebuf) ! 269: cp--; ! 270: *++cp = 0; ! 271: ! 272: /* ! 273: * Now search for the beginning of the file name. ! 274: */ ! 275: ! 276: while (cp > linebuf && !any(*cp, "\t ")) ! 277: cp--; ! 278: if (*cp == '\0') { ! 279: printf("No file specified.\n"); ! 280: return(NOSTR); ! 281: } ! 282: if (any(*cp, " \t")) ! 283: *cp++ = 0; ! 284: else ! 285: *flag = 0; ! 286: return(cp); ! 287: } ! 288: ! 289: /* ! 290: * Delete messages. ! 291: */ ! 292: ! 293: delete(msgvec) ! 294: int msgvec[]; ! 295: { ! 296: return(delm(msgvec)); ! 297: } ! 298: ! 299: /* ! 300: * Delete messages, then type the new dot. ! 301: */ ! 302: ! 303: deltype(msgvec) ! 304: int msgvec[]; ! 305: { ! 306: int list[2]; ! 307: int lastdot; ! 308: ! 309: lastdot = dot - &message[0] + 1; ! 310: if (delm(msgvec) >= 0) { ! 311: list[0] = dot - &message[0]; ! 312: list[0]++; ! 313: if (list[0] > lastdot) { ! 314: touch(list[0]); ! 315: list[1] = NULL; ! 316: return(type(list)); ! 317: } ! 318: printf("At EOF\n"); ! 319: return(0); ! 320: } ! 321: else { ! 322: printf("No more messages\n"); ! 323: return(0); ! 324: } ! 325: } ! 326: ! 327: /* ! 328: * Delete the indicated messages. ! 329: * Set dot to some nice place afterwards. ! 330: * Internal interface. ! 331: */ ! 332: ! 333: delm(msgvec) ! 334: int *msgvec; ! 335: { ! 336: register struct message *mp; ! 337: register *ip, mesg; ! 338: int last; ! 339: ! 340: last = NULL; ! 341: for (ip = msgvec; *ip != NULL; ip++) { ! 342: mesg = *ip; ! 343: touch(mesg); ! 344: mp = &message[mesg-1]; ! 345: mp->m_flag |= MDELETED|MTOUCH; ! 346: mp->m_flag &= ~(MPRESERVE|MSAVED|MBOX); ! 347: last = mesg; ! 348: } ! 349: if (last != NULL) { ! 350: dot = &message[last-1]; ! 351: last = first(0, MDELETED); ! 352: if (last != NULL) { ! 353: dot = &message[last-1]; ! 354: return(0); ! 355: } ! 356: else { ! 357: dot = &message[0]; ! 358: return(-1); ! 359: } ! 360: } ! 361: ! 362: /* ! 363: * Following can't happen -- it keeps lint happy ! 364: */ ! 365: ! 366: return(-1); ! 367: } ! 368: ! 369: /* ! 370: * Undelete the indicated messages. ! 371: */ ! 372: ! 373: undelete(msgvec) ! 374: int *msgvec; ! 375: { ! 376: register struct message *mp; ! 377: register *ip, mesg; ! 378: ! 379: for (ip = msgvec; ip-msgvec < msgCount; ip++) { ! 380: mesg = *ip; ! 381: if (mesg == 0) ! 382: return; ! 383: touch(mesg); ! 384: mp = &message[mesg-1]; ! 385: dot = mp; ! 386: mp->m_flag &= ~MDELETED; ! 387: } ! 388: } ! 389: ! 390: /* ! 391: * Interactively dump core on "core" ! 392: */ ! 393: ! 394: core() ! 395: { ! 396: register int pid; ! 397: int status; ! 398: ! 399: if ((pid = vfork()) == -1) { ! 400: perror("fork"); ! 401: return(1); ! 402: } ! 403: if (pid == 0) { ! 404: sigchild(); ! 405: abort(); ! 406: _exit(1); ! 407: } ! 408: printf("Okie dokie"); ! 409: fflush(stdout); ! 410: while (wait(&status) != pid) ! 411: ; ! 412: if (status & 0200) ! 413: printf(" -- Core dumped\n"); ! 414: else ! 415: printf("\n"); ! 416: } ! 417: ! 418: /* ! 419: * Clobber as many bytes of stack as the user requests. ! 420: */ ! 421: clobber(argv) ! 422: char **argv; ! 423: { ! 424: register int times; ! 425: ! 426: if (argv[0] == 0) ! 427: times = 1; ! 428: else ! 429: times = (atoi(argv[0]) + 511) / 512; ! 430: clob1(times); ! 431: } ! 432: ! 433: /* ! 434: * Clobber the stack. ! 435: */ ! 436: clob1(n) ! 437: { ! 438: char buf[512]; ! 439: register char *cp; ! 440: ! 441: if (n <= 0) ! 442: return; ! 443: for (cp = buf; cp < &buf[512]; *cp++ = 0xFF) ! 444: ; ! 445: clob1(n - 1); ! 446: } ! 447: ! 448: /* ! 449: * Add the given header fields to the ignored list. ! 450: * If no arguments, print the current list of ignored fields. ! 451: */ ! 452: igfield(list) ! 453: char *list[]; ! 454: { ! 455: char field[BUFSIZ]; ! 456: register int h; ! 457: register struct ignore *igp; ! 458: char **ap; ! 459: ! 460: if (argcount(list) == 0) ! 461: return(igshow()); ! 462: for (ap = list; *ap != 0; ap++) { ! 463: if (isign(*ap)) ! 464: continue; ! 465: istrcpy(field, *ap); ! 466: h = hash(field); ! 467: igp = (struct ignore *) calloc(1, sizeof (struct ignore)); ! 468: igp->i_field = calloc(strlen(field) + 1, sizeof (char)); ! 469: strcpy(igp->i_field, field); ! 470: igp->i_link = ignore[h]; ! 471: ignore[h] = igp; ! 472: } ! 473: return(0); ! 474: } ! 475: ! 476: /* ! 477: * Print out all currently ignored fields. ! 478: */ ! 479: igshow() ! 480: { ! 481: register int h, count; ! 482: struct ignore *igp; ! 483: char **ap, **ring; ! 484: int igcomp(); ! 485: ! 486: count = 0; ! 487: for (h = 0; h < HSHSIZE; h++) ! 488: for (igp = ignore[h]; igp != 0; igp = igp->i_link) ! 489: count++; ! 490: if (count == 0) { ! 491: printf("No fields currently being ignored.\n"); ! 492: return(0); ! 493: } ! 494: ring = (char **) salloc((count + 1) * sizeof (char *)); ! 495: ap = ring; ! 496: for (h = 0; h < HSHSIZE; h++) ! 497: for (igp = ignore[h]; igp != 0; igp = igp->i_link) ! 498: *ap++ = igp->i_field; ! 499: *ap = 0; ! 500: qsort(ring, count, sizeof (char *), igcomp); ! 501: for (ap = ring; *ap != 0; ap++) ! 502: printf("%s\n", *ap); ! 503: return(0); ! 504: } ! 505: ! 506: /* ! 507: * Compare two names for sorting ignored field list. ! 508: */ ! 509: igcomp(l, r) ! 510: char **l, **r; ! 511: { ! 512: ! 513: return(strcmp(*l, *r)); ! 514: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.