|
|
1.1 ! root 1: /*- ! 2: * Copyright (c) 1980 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)cmd1.c 5.21 (Berkeley) 6/25/90"; ! 22: #endif /* not lint */ ! 23: ! 24: #include "rcv.h" ! 25: ! 26: /* ! 27: * Mail -- a mail program ! 28: * ! 29: * User commands. ! 30: */ ! 31: ! 32: /* ! 33: * Print the current active headings. ! 34: * Don't change dot if invoker didn't give an argument. ! 35: */ ! 36: ! 37: static int screen; ! 38: ! 39: headers(msgvec) ! 40: int *msgvec; ! 41: { ! 42: register int n, mesg, flag; ! 43: register struct message *mp; ! 44: int size; ! 45: ! 46: size = screensize(); ! 47: n = msgvec[0]; ! 48: if (n != 0) ! 49: screen = (n-1)/size; ! 50: if (screen < 0) ! 51: screen = 0; ! 52: mp = &message[screen * size]; ! 53: if (mp >= &message[msgCount]) ! 54: mp = &message[msgCount - size]; ! 55: if (mp < &message[0]) ! 56: mp = &message[0]; ! 57: flag = 0; ! 58: mesg = mp - &message[0]; ! 59: if (dot != &message[n-1]) ! 60: dot = mp; ! 61: for (; mp < &message[msgCount]; mp++) { ! 62: mesg++; ! 63: if (mp->m_flag & MDELETED) ! 64: continue; ! 65: if (flag++ >= size) ! 66: break; ! 67: printhead(mesg); ! 68: } ! 69: if (flag == 0) { ! 70: printf("No more mail.\n"); ! 71: return(1); ! 72: } ! 73: return(0); ! 74: } ! 75: ! 76: /* ! 77: * Scroll to the next/previous screen ! 78: */ ! 79: scroll(arg) ! 80: char arg[]; ! 81: { ! 82: register int s, size; ! 83: int cur[1]; ! 84: ! 85: cur[0] = 0; ! 86: size = screensize(); ! 87: s = screen; ! 88: switch (*arg) { ! 89: case 0: ! 90: case '+': ! 91: s++; ! 92: if (s * size > msgCount) { ! 93: printf("On last screenful of messages\n"); ! 94: return(0); ! 95: } ! 96: screen = s; ! 97: break; ! 98: ! 99: case '-': ! 100: if (--s < 0) { ! 101: printf("On first screenful of messages\n"); ! 102: return(0); ! 103: } ! 104: screen = s; ! 105: break; ! 106: ! 107: default: ! 108: printf("Unrecognized scrolling command \"%s\"\n", arg); ! 109: return(1); ! 110: } ! 111: return(headers(cur)); ! 112: } ! 113: ! 114: /* ! 115: * Compute screen size. ! 116: */ ! 117: screensize() ! 118: { ! 119: int s; ! 120: char *cp; ! 121: ! 122: if ((cp = value("screen")) != NOSTR && (s = atoi(cp)) > 0) ! 123: return s; ! 124: return screenheight - 4; ! 125: } ! 126: ! 127: /* ! 128: * Print out the headlines for each message ! 129: * in the passed message list. ! 130: */ ! 131: ! 132: from(msgvec) ! 133: int *msgvec; ! 134: { ! 135: register int *ip; ! 136: ! 137: for (ip = msgvec; *ip != NULL; ip++) ! 138: printhead(*ip); ! 139: if (--ip >= msgvec) ! 140: dot = &message[*ip - 1]; ! 141: return(0); ! 142: } ! 143: ! 144: /* ! 145: * Print out the header of a specific message. ! 146: * This is a slight improvement to the standard one. ! 147: */ ! 148: ! 149: printhead(mesg) ! 150: { ! 151: struct message *mp; ! 152: char headline[LINESIZE], wcount[LINESIZE], *subjline, dispc, curind; ! 153: char pbuf[BUFSIZ]; ! 154: struct headline hl; ! 155: int subjlen; ! 156: char *name; ! 157: ! 158: mp = &message[mesg-1]; ! 159: (void) readline(setinput(mp), headline, LINESIZE); ! 160: if ((subjline = hfield("subject", mp)) == NOSTR) ! 161: subjline = hfield("subj", mp); ! 162: /* ! 163: * Bletch! ! 164: */ ! 165: curind = dot == mp ? '>' : ' '; ! 166: dispc = ' '; ! 167: if (mp->m_flag & MSAVED) ! 168: dispc = '*'; ! 169: if (mp->m_flag & MPRESERVE) ! 170: dispc = 'P'; ! 171: if ((mp->m_flag & (MREAD|MNEW)) == MNEW) ! 172: dispc = 'N'; ! 173: if ((mp->m_flag & (MREAD|MNEW)) == 0) ! 174: dispc = 'U'; ! 175: if (mp->m_flag & MBOX) ! 176: dispc = 'M'; ! 177: parse(headline, &hl, pbuf); ! 178: sprintf(wcount, "%3d/%-5ld", mp->m_lines, mp->m_size); ! 179: subjlen = screenwidth - 50 - strlen(wcount); ! 180: name = value("show-rcpt") != NOSTR ? ! 181: skin(hfield("to", mp)) : nameof(mp, 0); ! 182: if (subjline == NOSTR || subjlen < 0) /* pretty pathetic */ ! 183: printf("%c%c%3d %-20.20s %16.16s %s\n", ! 184: curind, dispc, mesg, name, hl.l_date, wcount); ! 185: else ! 186: printf("%c%c%3d %-20.20s %16.16s %s \"%.*s\"\n", ! 187: curind, dispc, mesg, name, hl.l_date, wcount, ! 188: subjlen, subjline); ! 189: } ! 190: ! 191: /* ! 192: * Print out the value of dot. ! 193: */ ! 194: ! 195: pdot() ! 196: { ! 197: printf("%d\n", dot - &message[0] + 1); ! 198: return(0); ! 199: } ! 200: ! 201: /* ! 202: * Print out all the possible commands. ! 203: */ ! 204: ! 205: pcmdlist() ! 206: { ! 207: register struct cmd *cp; ! 208: register int cc; ! 209: extern struct cmd cmdtab[]; ! 210: ! 211: printf("Commands are:\n"); ! 212: for (cc = 0, cp = cmdtab; cp->c_name != NULL; cp++) { ! 213: cc += strlen(cp->c_name) + 2; ! 214: if (cc > 72) { ! 215: printf("\n"); ! 216: cc = strlen(cp->c_name) + 2; ! 217: } ! 218: if ((cp+1)->c_name != NOSTR) ! 219: printf("%s, ", cp->c_name); ! 220: else ! 221: printf("%s\n", cp->c_name); ! 222: } ! 223: return(0); ! 224: } ! 225: ! 226: /* ! 227: * Paginate messages, honor ignored fields. ! 228: */ ! 229: more(msgvec) ! 230: int *msgvec; ! 231: { ! 232: return (type1(msgvec, 1, 1)); ! 233: } ! 234: ! 235: /* ! 236: * Paginate messages, even printing ignored fields. ! 237: */ ! 238: More(msgvec) ! 239: int *msgvec; ! 240: { ! 241: ! 242: return (type1(msgvec, 0, 1)); ! 243: } ! 244: ! 245: /* ! 246: * Type out messages, honor ignored fields. ! 247: */ ! 248: type(msgvec) ! 249: int *msgvec; ! 250: { ! 251: ! 252: return(type1(msgvec, 1, 0)); ! 253: } ! 254: ! 255: /* ! 256: * Type out messages, even printing ignored fields. ! 257: */ ! 258: Type(msgvec) ! 259: int *msgvec; ! 260: { ! 261: ! 262: return(type1(msgvec, 0, 0)); ! 263: } ! 264: ! 265: /* ! 266: * Type out the messages requested. ! 267: */ ! 268: jmp_buf pipestop; ! 269: ! 270: type1(msgvec, doign, page) ! 271: int *msgvec; ! 272: { ! 273: register *ip; ! 274: register struct message *mp; ! 275: register char *cp; ! 276: int nlines; ! 277: int brokpipe(); ! 278: FILE *obuf; ! 279: ! 280: obuf = stdout; ! 281: if (setjmp(pipestop)) ! 282: goto close_pipe; ! 283: if (value("interactive") != NOSTR && ! 284: (page || (cp = value("crt")) != NOSTR)) { ! 285: nlines = 0; ! 286: if (!page) { ! 287: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) ! 288: nlines += message[*ip - 1].m_lines; ! 289: } ! 290: if (page || nlines > (*cp ? atoi(cp) : realscreenheight)) { ! 291: cp = value("PAGER"); ! 292: if (cp == NULL || *cp == '\0') ! 293: cp = _PATH_MORE; ! 294: obuf = Popen(cp, "w"); ! 295: if (obuf == NULL) { ! 296: perror(cp); ! 297: obuf = stdout; ! 298: } else ! 299: signal(SIGPIPE, brokpipe); ! 300: } ! 301: } ! 302: for (ip = msgvec; *ip && ip - msgvec < msgCount; ip++) { ! 303: mp = &message[*ip - 1]; ! 304: touch(mp); ! 305: dot = mp; ! 306: if (value("quiet") == NOSTR) ! 307: fprintf(obuf, "Message %d:\n", *ip); ! 308: (void) send(mp, obuf, doign ? ignore : 0, NOSTR); ! 309: } ! 310: close_pipe: ! 311: if (obuf != stdout) { ! 312: /* ! 313: * Ignore SIGPIPE so it can't cause a duplicate close. ! 314: */ ! 315: signal(SIGPIPE, SIG_IGN); ! 316: Pclose(obuf); ! 317: signal(SIGPIPE, SIG_DFL); ! 318: } ! 319: return(0); ! 320: } ! 321: ! 322: /* ! 323: * Respond to a broken pipe signal -- ! 324: * probably caused by quitting more. ! 325: */ ! 326: ! 327: brokpipe() ! 328: { ! 329: longjmp(pipestop, 1); ! 330: } ! 331: ! 332: /* ! 333: * Print the top so many lines of each desired message. ! 334: * The number of lines is taken from the variable "toplines" ! 335: * and defaults to 5. ! 336: */ ! 337: ! 338: top(msgvec) ! 339: int *msgvec; ! 340: { ! 341: register int *ip; ! 342: register struct message *mp; ! 343: int c, topl, lines, lineb; ! 344: char *valtop, linebuf[LINESIZE]; ! 345: FILE *ibuf; ! 346: ! 347: topl = 5; ! 348: valtop = value("toplines"); ! 349: if (valtop != NOSTR) { ! 350: topl = atoi(valtop); ! 351: if (topl < 0 || topl > 10000) ! 352: topl = 5; ! 353: } ! 354: lineb = 1; ! 355: for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { ! 356: mp = &message[*ip - 1]; ! 357: touch(mp); ! 358: dot = mp; ! 359: if (value("quiet") == NOSTR) ! 360: printf("Message %d:\n", *ip); ! 361: ibuf = setinput(mp); ! 362: c = mp->m_lines; ! 363: if (!lineb) ! 364: printf("\n"); ! 365: for (lines = 0; lines < c && lines <= topl; lines++) { ! 366: if (readline(ibuf, linebuf, LINESIZE) < 0) ! 367: break; ! 368: puts(linebuf); ! 369: lineb = blankline(linebuf); ! 370: } ! 371: } ! 372: return(0); ! 373: } ! 374: ! 375: /* ! 376: * Touch all the given messages so that they will ! 377: * get mboxed. ! 378: */ ! 379: stouch(msgvec) ! 380: int msgvec[]; ! 381: { ! 382: register int *ip; ! 383: ! 384: for (ip = msgvec; *ip != 0; ip++) { ! 385: dot = &message[*ip-1]; ! 386: dot->m_flag |= MTOUCH; ! 387: dot->m_flag &= ~MPRESERVE; ! 388: } ! 389: return(0); ! 390: } ! 391: ! 392: /* ! 393: * Make sure all passed messages get mboxed. ! 394: */ ! 395: ! 396: mboxit(msgvec) ! 397: int msgvec[]; ! 398: { ! 399: register int *ip; ! 400: ! 401: for (ip = msgvec; *ip != 0; ip++) { ! 402: dot = &message[*ip-1]; ! 403: dot->m_flag |= MTOUCH|MBOX; ! 404: dot->m_flag &= ~MPRESERVE; ! 405: } ! 406: return(0); ! 407: } ! 408: ! 409: /* ! 410: * List the folders the user currently has. ! 411: */ ! 412: folders() ! 413: { ! 414: char dirname[BUFSIZ]; ! 415: char *cmd; ! 416: ! 417: if (getfold(dirname) < 0) { ! 418: printf("No value set for \"folder\"\n"); ! 419: return 1; ! 420: } ! 421: if ((cmd = value("LISTER")) == NOSTR) ! 422: cmd = "ls"; ! 423: (void) run_command(cmd, 0, -1, -1, dirname, NOSTR); ! 424: return 0; ! 425: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.