|
|
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) == 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, *disp; ! 98: int f, *msgvec, lc, cc, t; ! 99: FILE *obuf; ! 100: struct stat statb; ! 101: ! 102: msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); ! 103: if ((file = snarf(str, &f)) == NOSTR) ! 104: return(1); ! 105: if (!f) { ! 106: *msgvec = first(0, MMNORM); ! 107: if (*msgvec == NULL) { ! 108: printf("No messages to save.\n"); ! 109: return(1); ! 110: } ! 111: msgvec[1] = NULL; ! 112: } ! 113: if (f && getmsglist(str, msgvec, 0) < 0) ! 114: return(1); ! 115: if ((file = expand(file)) == NOSTR) ! 116: return(1); ! 117: printf("\"%s\" ", file); ! 118: flush(); ! 119: if (stat(file, &statb) >= 0) ! 120: disp = "[Appended]"; ! 121: else ! 122: disp = "[New file]"; ! 123: if ((obuf = fopen(file, "a")) == NULL) { ! 124: perror(NOSTR); ! 125: return(1); ! 126: } ! 127: cc = lc = 0; ! 128: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { ! 129: mesg = *ip; ! 130: touch(mesg); ! 131: mp = &message[mesg-1]; ! 132: if ((t = send(mp, obuf)) < 0) { ! 133: perror(file); ! 134: fclose(obuf); ! 135: return(1); ! 136: } ! 137: lc += t; ! 138: cc += msize(mp); ! 139: mp->m_flag |= MSAVED; ! 140: } ! 141: fflush(obuf); ! 142: if (ferror(obuf)) ! 143: perror(file); ! 144: fclose(obuf); ! 145: printf("%s %d/%d\n", disp, lc, cc); ! 146: return(0); ! 147: } ! 148: ! 149: /* ! 150: * Write the indicated messages at the end of the passed ! 151: * file name, minus header and trailing blank line. ! 152: */ ! 153: ! 154: swrite(str) ! 155: char str[]; ! 156: { ! 157: register int *ip, mesg; ! 158: register struct message *mp; ! 159: register char *file, *disp; ! 160: char linebuf[BUFSIZ]; ! 161: int f, *msgvec, lc, cc, t; ! 162: FILE *obuf, *mesf; ! 163: struct stat statb; ! 164: ! 165: msgvec = (int *) salloc((msgCount + 2) * sizeof *msgvec); ! 166: if ((file = snarf(str, &f)) == NOSTR) ! 167: return(1); ! 168: if ((file = expand(file)) == NOSTR) ! 169: return(1); ! 170: if (!f) { ! 171: *msgvec = first(0, MMNORM); ! 172: if (*msgvec == NULL) { ! 173: printf("No messages to write.\n"); ! 174: return(1); ! 175: } ! 176: msgvec[1] = NULL; ! 177: } ! 178: if (f && getmsglist(str, msgvec, 0) < 0) ! 179: return(1); ! 180: printf("\"%s\" ", file); ! 181: flush(); ! 182: if (stat(file, &statb) >= 0) ! 183: disp = "[Appended]"; ! 184: else ! 185: disp = "[New file]"; ! 186: if ((obuf = fopen(file, "a")) == NULL) { ! 187: perror(NOSTR); ! 188: return(1); ! 189: } ! 190: cc = lc = 0; ! 191: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { ! 192: mesg = *ip; ! 193: touch(mesg); ! 194: mp = &message[mesg-1]; ! 195: mesf = setinput(mp); ! 196: t = mp->m_lines - 2; ! 197: readline(mesf, linebuf); ! 198: while (t-- > 0) { ! 199: fgets(linebuf, BUFSIZ, mesf); ! 200: fputs(linebuf, obuf); ! 201: cc += strlen(linebuf); ! 202: } ! 203: lc += mp->m_lines - 2; ! 204: mp->m_flag |= MSAVED; ! 205: } ! 206: fflush(obuf); ! 207: if (ferror(obuf)) ! 208: perror(file); ! 209: fclose(obuf); ! 210: printf("%s %d/%d\n", disp, lc, cc); ! 211: return(0); ! 212: } ! 213: ! 214: /* ! 215: * Snarf the file from the end of the command line and ! 216: * return a pointer to it. If there is no file attached, ! 217: * just return NOSTR. Put a null in front of the file ! 218: * name so that the message list processing won't see it, ! 219: * unless the file name is the only thing on the line, in ! 220: * which case, return 0 in the reference flag variable. ! 221: */ ! 222: ! 223: char * ! 224: snarf(linebuf, flag) ! 225: char linebuf[]; ! 226: int *flag; ! 227: { ! 228: register char *cp; ! 229: ! 230: *flag = 1; ! 231: cp = strlen(linebuf) + linebuf - 1; ! 232: ! 233: /* ! 234: * Strip away trailing blanks. ! 235: */ ! 236: ! 237: while (*cp == ' ' && cp > linebuf) ! 238: cp--; ! 239: *++cp = 0; ! 240: ! 241: /* ! 242: * Now search for the beginning of the file name. ! 243: */ ! 244: ! 245: while (cp > linebuf && !any(*cp, "\t ")) ! 246: cp--; ! 247: if (*cp == '\0') { ! 248: printf("No file specified.\n"); ! 249: return(NOSTR); ! 250: } ! 251: if (any(*cp, " \t")) ! 252: *cp++ = 0; ! 253: else ! 254: *flag = 0; ! 255: return(cp); ! 256: } ! 257: ! 258: /* ! 259: * Delete messages. ! 260: */ ! 261: ! 262: delete(msgvec) ! 263: int msgvec[]; ! 264: { ! 265: return(delm(msgvec)); ! 266: } ! 267: ! 268: /* ! 269: * Delete messages, then type the new dot. ! 270: */ ! 271: ! 272: deltype(msgvec) ! 273: int msgvec[]; ! 274: { ! 275: int list[2]; ! 276: ! 277: if (delm(msgvec) >= 0) { ! 278: list[0] = dot - &message[0]; ! 279: list[0]++; ! 280: touch(list[0]); ! 281: list[1] = NULL; ! 282: return(type(list)); ! 283: } ! 284: else { ! 285: printf("No more messages\n"); ! 286: return(0); ! 287: } ! 288: } ! 289: ! 290: /* ! 291: * Delete the indicated messages. ! 292: * Set dot to some nice place afterwards. ! 293: * Internal interface. ! 294: */ ! 295: ! 296: delm(msgvec) ! 297: int *msgvec; ! 298: { ! 299: register struct message *mp; ! 300: register *ip, mesg; ! 301: int last; ! 302: ! 303: last = NULL; ! 304: for (ip = msgvec; *ip != NULL; ip++) { ! 305: mesg = *ip; ! 306: touch(mesg); ! 307: mp = &message[mesg-1]; ! 308: mp->m_flag |= MDELETED; ! 309: mp->m_flag &= ~(MPRESERVE|MSAVED); ! 310: last = mesg; ! 311: } ! 312: if (last != NULL) { ! 313: dot = &message[last-1]; ! 314: last = first(0, MDELETED); ! 315: if (last != NULL) { ! 316: dot = &message[last-1]; ! 317: return(0); ! 318: } ! 319: else { ! 320: dot = &message[0]; ! 321: return(-1); ! 322: } ! 323: } ! 324: ! 325: /* ! 326: * Following can't happen -- it keeps lint happy ! 327: */ ! 328: ! 329: return(-1); ! 330: } ! 331: ! 332: /* ! 333: * Undelete the indicated messages. ! 334: */ ! 335: ! 336: undelete(msgvec) ! 337: int *msgvec; ! 338: { ! 339: register struct message *mp; ! 340: register *ip, mesg; ! 341: ! 342: for (ip = msgvec; ip-msgvec < msgCount; ip++) { ! 343: mesg = *ip; ! 344: if (mesg == 0) ! 345: return; ! 346: touch(mesg); ! 347: mp = &message[mesg-1]; ! 348: dot = mp; ! 349: mp->m_flag &= ~MDELETED; ! 350: } ! 351: } ! 352: ! 353: /* ! 354: * Interactively dump core on "core" ! 355: */ ! 356: ! 357: core() ! 358: { ! 359: register int pid; ! 360: int status; ! 361: ! 362: if ((pid = vfork()) == -1) { ! 363: perror("fork"); ! 364: return(1); ! 365: } ! 366: if (pid == 0) { ! 367: abort(); ! 368: _exit(1); ! 369: } ! 370: printf("Okie dokie"); ! 371: fflush(stdout); ! 372: while (wait(&status) != pid) ! 373: ; ! 374: if (status & 0200) ! 375: printf(" -- Core dumped\n"); ! 376: else ! 377: printf("\n"); ! 378: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.