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: static char *SccsId = "@(#)cmd2.c	2.10 10/21/82";
  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: }

Defined functions

clob1 defined in line 436; used 2 times
clobber defined in line 421; used 2 times
copycmd defined in line 108; used 2 times
core defined in line 394; used 4 times
delete defined in line 293; used 2 times
delm defined in line 333; used 2 times
deltype defined in line 303; used 3 times
igcomp defined in line 509; used 2 times
igfield defined in line 452; used 3 times
igshow defined in line 479; used 1 times
next defined in line 20; used 2 times
save defined in line 98; used 2 times
save1 defined in line 119; used 2 times
snarf defined in line 254; used 3 times
swrite defined in line 185; used 2 times
undelete defined in line 373; used 2 times

Defined variables

SccsId defined in line 12; never used
Last modified: 1982-10-21
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1196
Valid CSS Valid XHTML 1.0 Strict