1 # 2 #include "rcv.h" 3 #include <sys/stat.h> 4 5 /* 6 * Mail -- a mail program 7 * 8 * User commands. 9 */ 10 11 static char *SccsId = "@(#)cmd1.c 1.1 10/08/80"; 12 13 /* 14 * Print the current active headings. 15 */ 16 17 static int screen; 18 19 headers(msgvec) 20 int *msgvec; 21 { 22 register int n, mesg, flag; 23 register struct message *mp; 24 25 n = msgvec[0]; 26 if (n != 0) 27 screen = (n-1)/SCREEN; 28 if (screen < 0) 29 screen = 0; 30 mp = &message[screen * SCREEN]; 31 if (mp >= &message[msgCount]) 32 mp = &message[msgCount - SCREEN]; 33 if (mp < &message[0]) 34 mp = &message[0]; 35 flag = 0; 36 mesg = mp - &message[0]; 37 dot = mp; 38 for (; mp < &message[msgCount]; mp++) { 39 mesg++; 40 if (mp->m_flag & MDELETED) 41 continue; 42 if (flag++ >= SCREEN) 43 break; 44 printhead(mesg); 45 sreset(); 46 } 47 if (flag == 0) { 48 printf("No more mail.\n"); 49 return(1); 50 } 51 return(0); 52 } 53 54 /* 55 * Scroll to the next/previous screen 56 */ 57 58 scroll(arg) 59 char arg[]; 60 { 61 register int s; 62 int cur[1]; 63 64 cur[0] = 0; 65 s = screen; 66 switch (*arg) { 67 case 0: 68 case '+': 69 s++; 70 if (s*SCREEN > msgCount) { 71 printf("On last screenful of messages\n"); 72 return(0); 73 } 74 screen = s; 75 break; 76 77 case '-': 78 if (--s < 0) { 79 printf("On first screenful of messages\n"); 80 return(0); 81 } 82 screen = s; 83 break; 84 85 default: 86 printf("Unrecognized scrolling command \"%s\"\n", arg); 87 return(1); 88 } 89 return(headers(cur)); 90 } 91 92 93 /* 94 * Print out the headlines for each message 95 * in the passed message list. 96 */ 97 98 from(msgvec) 99 int *msgvec; 100 { 101 register int *ip; 102 103 for (ip = msgvec; *ip != NULL; ip++) { 104 printhead(*ip); 105 sreset(); 106 } 107 if (--ip >= msgvec) 108 dot = &message[*ip - 1]; 109 return(0); 110 } 111 112 /* 113 * Print out the header of a specific message. 114 * This is a slight improvement to the standard one. 115 */ 116 117 printhead(mesg) 118 { 119 struct message *mp; 120 FILE *ibuf; 121 char headline[LINESIZE], wcount[10], *subjline, dispc; 122 char pbuf[BUFSIZ]; 123 int s; 124 struct headline hl; 125 register char *cp; 126 127 mp = &message[mesg-1]; 128 ibuf = setinput(mp); 129 readline(ibuf, headline); 130 subjline = hfield("subject", mp); 131 if (subjline == NOSTR) 132 subjline = hfield("subj", mp); 133 134 /* 135 * Bletch! 136 */ 137 138 if (subjline != NOSTR && strlen(subjline) > 28) 139 subjline[29] = '\0'; 140 dispc = ' '; 141 if (mp->m_flag & MSAVED) 142 dispc = '*'; 143 if (mp->m_flag & MPRESERVE) 144 dispc = 'P'; 145 parse(headline, &hl, pbuf); 146 sprintf(wcount, " %d/%d", mp->m_lines, mp->m_size); 147 s = strlen(wcount); 148 cp = wcount + s; 149 while (s < 7) 150 s++, *cp++ = ' '; 151 *cp = '\0'; 152 if (subjline != NOSTR) 153 printf("%c%3d %-8s %16.16s %s \"%s\"\n", dispc, mesg, 154 nameof(mp), hl.l_date, wcount, subjline); 155 else 156 printf("%c%3d %-8s %16.16s %s\n", dispc, mesg, 157 nameof(mp), hl.l_date, wcount); 158 } 159 160 /* 161 * Print out the value of dot. 162 */ 163 164 pdot() 165 { 166 printf("%d\n", dot - &message[0] + 1); 167 return(0); 168 } 169 170 /* 171 * Print out all the possible commands. 172 */ 173 174 pcmdlist() 175 { 176 register struct cmd *cp; 177 register int cc; 178 extern struct cmd cmdtab[]; 179 180 printf("Commands are:\n"); 181 for (cc = 0, cp = cmdtab; cp->c_name != NULL; cp++) { 182 cc += strlen(cp->c_name) + 2; 183 if (cc > 72) { 184 printf("\n"); 185 cc = strlen(cp->c_name) + 2; 186 } 187 if ((cp+1)->c_name != NOSTR) 188 printf("%s, ", cp->c_name); 189 else 190 printf("%s\n", cp->c_name); 191 } 192 return(0); 193 } 194 195 /* 196 * Type out the messages requested. 197 */ 198 199 type(msgvec) 200 int *msgvec; 201 { 202 register *ip; 203 register struct message *mp; 204 register int mesg; 205 int c; 206 FILE *ibuf; 207 208 for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { 209 mesg = *ip; 210 touch(mesg); 211 mp = &message[mesg-1]; 212 dot = mp; 213 print(mp); 214 } 215 return(0); 216 } 217 218 /* 219 * Print the indicated message on standard output. 220 */ 221 222 print(mp) 223 register struct message *mp; 224 { 225 226 if (value("quiet") == NOSTR) 227 printf("Message %2d:\n", mp - &message[0] + 1); 228 touch(mp - &message[0] + 1); 229 send(mp, stdout); 230 } 231 232 /* 233 * Print the top so many lines of each desired message. 234 * The number of lines is taken from the variable "toplines" 235 * and defaults to 5. 236 */ 237 238 top(msgvec) 239 int *msgvec; 240 { 241 register int *ip; 242 register struct message *mp; 243 register int mesg; 244 int c, topl, lines, lineb; 245 char *valtop, linebuf[LINESIZE]; 246 FILE *ibuf; 247 248 topl = 5; 249 valtop = value("toplines"); 250 if (valtop != NOSTR) { 251 topl = atoi(valtop); 252 if (topl < 0 || topl > 10000) 253 topl = 5; 254 } 255 lineb = 1; 256 for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) { 257 mesg = *ip; 258 touch(mesg); 259 mp = &message[mesg-1]; 260 dot = mp; 261 if (value("quiet") == NOSTR) 262 printf("Message %2d:\n", mesg); 263 ibuf = setinput(mp); 264 c = mp->m_lines; 265 if (!lineb) 266 printf("\n"); 267 for (lines = 0; lines < c && lines <= topl; lines++) { 268 if (readline(ibuf, linebuf) <= 0) 269 break; 270 puts(linebuf); 271 lineb = blankline(linebuf); 272 } 273 } 274 return(0); 275 } 276 277 /* 278 * Touch all the given messages so that they will 279 * get mboxed. 280 */ 281 282 stouch(msgvec) 283 int msgvec[]; 284 { 285 register int *ip; 286 287 for (ip = msgvec; *ip != 0; ip++) { 288 touch(*ip); 289 dot = &message[*ip-1]; 290 dot->m_flag &= ~MPRESERVE; 291 } 292 return(0); 293 } 294