Deleted Added
full compact
cmd3.c (216370) cmd3.c (216564)
1/*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 19 unchanged lines hidden (view full) ---

28 */
29
30#ifndef lint
31#if 0
32static char sccsid[] = "@(#)cmd3.c 8.2 (Berkeley) 4/20/95";
33#endif
34#endif /* not lint */
35#include <sys/cdefs.h>
1/*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 19 unchanged lines hidden (view full) ---

28 */
29
30#ifndef lint
31#if 0
32static char sccsid[] = "@(#)cmd3.c 8.2 (Berkeley) 4/20/95";
33#endif
34#endif /* not lint */
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD: head/usr.bin/mail/cmd3.c 216370 2010-12-11 08:32:16Z joel $");
36__FBSDID("$FreeBSD: head/usr.bin/mail/cmd3.c 216564 2010-12-19 16:25:23Z charnier $");
37
38#include "rcv.h"
39#include "extern.h"
40
41/*
42 * Mail -- a mail program
43 *
44 * Still more user commands.
45 */
46
47/*
48 * Process a shell escape by saving signals, ignoring signals,
49 * and forking a sh -c
50 */
51int
37
38#include "rcv.h"
39#include "extern.h"
40
41/*
42 * Mail -- a mail program
43 *
44 * Still more user commands.
45 */
46
47/*
48 * Process a shell escape by saving signals, ignoring signals,
49 * and forking a sh -c
50 */
51int
52shell(str)
53 char *str;
52shell(char *str)
54{
55 sig_t sigint = signal(SIGINT, SIG_IGN);
56 char *sh;
57 char cmd[BUFSIZ];
58
59 if (strlcpy(cmd, str, sizeof(cmd)) >= sizeof(cmd))
60 return (1);
61 if (bangexp(cmd, sizeof(cmd)) < 0)

--- 6 unchanged lines hidden (view full) ---

68 return (0);
69}
70
71/*
72 * Fork an interactive shell.
73 */
74/*ARGSUSED*/
75int
53{
54 sig_t sigint = signal(SIGINT, SIG_IGN);
55 char *sh;
56 char cmd[BUFSIZ];
57
58 if (strlcpy(cmd, str, sizeof(cmd)) >= sizeof(cmd))
59 return (1);
60 if (bangexp(cmd, sizeof(cmd)) < 0)

--- 6 unchanged lines hidden (view full) ---

67 return (0);
68}
69
70/*
71 * Fork an interactive shell.
72 */
73/*ARGSUSED*/
74int
76dosh(str)
77 char *str;
75dosh(char *str __unused)
78{
79 sig_t sigint = signal(SIGINT, SIG_IGN);
80 char *sh;
81
82 if ((sh = value("SHELL")) == NULL)
83 sh = _PATH_CSHELL;
84 (void)run_command(sh, 0, -1, -1, NULL, NULL, NULL);
85 (void)signal(SIGINT, sigint);
86 printf("\n");
87 return (0);
88}
89
90/*
91 * Expand the shell escape by expanding unescaped !'s into the
92 * last issued command where possible.
93 */
94int
76{
77 sig_t sigint = signal(SIGINT, SIG_IGN);
78 char *sh;
79
80 if ((sh = value("SHELL")) == NULL)
81 sh = _PATH_CSHELL;
82 (void)run_command(sh, 0, -1, -1, NULL, NULL, NULL);
83 (void)signal(SIGINT, sigint);
84 printf("\n");
85 return (0);
86}
87
88/*
89 * Expand the shell escape by expanding unescaped !'s into the
90 * last issued command where possible.
91 */
92int
95bangexp(str, strsize)
96 char *str;
97 size_t strsize;
93bangexp(char *str, size_t strsize)
98{
99 char bangbuf[BUFSIZ];
100 static char lastbang[BUFSIZ];
101 char *cp, *cp2;
102 int n, changed = 0;
103
104 cp = str;
105 cp2 = bangbuf;

--- 37 unchanged lines hidden (view full) ---

143 return (0);
144}
145
146/*
147 * Print out a nice help message from some file or another.
148 */
149
150int
94{
95 char bangbuf[BUFSIZ];
96 static char lastbang[BUFSIZ];
97 char *cp, *cp2;
98 int n, changed = 0;
99
100 cp = str;
101 cp2 = bangbuf;

--- 37 unchanged lines hidden (view full) ---

139 return (0);
140}
141
142/*
143 * Print out a nice help message from some file or another.
144 */
145
146int
151help()
147help(void)
152{
153 int c;
154 FILE *f;
155
156 if ((f = Fopen(_PATH_HELP, "r")) == NULL) {
157 warn("%s", _PATH_HELP);
158 return (1);
159 }
160 while ((c = getc(f)) != EOF)
161 putchar(c);
162 (void)Fclose(f);
163 return (0);
164}
165
166/*
167 * Change user's working directory.
168 */
169int
148{
149 int c;
150 FILE *f;
151
152 if ((f = Fopen(_PATH_HELP, "r")) == NULL) {
153 warn("%s", _PATH_HELP);
154 return (1);
155 }
156 while ((c = getc(f)) != EOF)
157 putchar(c);
158 (void)Fclose(f);
159 return (0);
160}
161
162/*
163 * Change user's working directory.
164 */
165int
170schdir(arglist)
171 char **arglist;
166schdir(char **arglist)
172{
173 char *cp;
174
175 if (*arglist == NULL) {
176 if (homedir == NULL)
177 return (1);
178 cp = homedir;
179 } else
180 if ((cp = expand(*arglist)) == NULL)
181 return (1);
182 if (chdir(cp) < 0) {
183 warn("%s", cp);
184 return (1);
185 }
186 return (0);
187}
188
189int
167{
168 char *cp;
169
170 if (*arglist == NULL) {
171 if (homedir == NULL)
172 return (1);
173 cp = homedir;
174 } else
175 if ((cp = expand(*arglist)) == NULL)
176 return (1);
177 if (chdir(cp) < 0) {
178 warn("%s", cp);
179 return (1);
180 }
181 return (0);
182}
183
184int
190respond(msgvec)
191 int *msgvec;
185respond(int *msgvec)
192{
193 if (value("Replyall") == NULL && value("flipr") == NULL)
194 return (dorespond(msgvec));
195 else
196 return (doRespond(msgvec));
197}
198
199/*
200 * Reply to a list of messages. Extract each name from the
201 * message header and send them off to mail1()
202 */
203int
186{
187 if (value("Replyall") == NULL && value("flipr") == NULL)
188 return (dorespond(msgvec));
189 else
190 return (doRespond(msgvec));
191}
192
193/*
194 * Reply to a list of messages. Extract each name from the
195 * message header and send them off to mail1()
196 */
197int
204dorespond(msgvec)
205 int *msgvec;
198dorespond(int *msgvec)
206{
207 struct message *mp;
208 char *cp, *rcv, *replyto;
209 char **ap;
210 struct name *np;
211 struct header head;
212
213 if (msgvec[1] != 0) {

--- 48 unchanged lines hidden (view full) ---

262 return (0);
263}
264
265/*
266 * Modify the subject we are replying to to begin with Re: if
267 * it does not already.
268 */
269char *
199{
200 struct message *mp;
201 char *cp, *rcv, *replyto;
202 char **ap;
203 struct name *np;
204 struct header head;
205
206 if (msgvec[1] != 0) {

--- 48 unchanged lines hidden (view full) ---

255 return (0);
256}
257
258/*
259 * Modify the subject we are replying to to begin with Re: if
260 * it does not already.
261 */
262char *
270reedit(subj)
271 char *subj;
263reedit(char *subj)
272{
273 char *newsubj;
274
275 if (subj == NULL)
276 return (NULL);
277 if ((subj[0] == 'r' || subj[0] == 'R') &&
278 (subj[1] == 'e' || subj[1] == 'E') &&
279 subj[2] == ':')
280 return (subj);
281 newsubj = salloc(strlen(subj) + 5);
282 sprintf(newsubj, "Re: %s", subj);
283 return (newsubj);
284}
285
286/*
287 * Preserve the named messages, so that they will be sent
288 * back to the system mailbox.
289 */
290int
264{
265 char *newsubj;
266
267 if (subj == NULL)
268 return (NULL);
269 if ((subj[0] == 'r' || subj[0] == 'R') &&
270 (subj[1] == 'e' || subj[1] == 'E') &&
271 subj[2] == ':')
272 return (subj);
273 newsubj = salloc(strlen(subj) + 5);
274 sprintf(newsubj, "Re: %s", subj);
275 return (newsubj);
276}
277
278/*
279 * Preserve the named messages, so that they will be sent
280 * back to the system mailbox.
281 */
282int
291preserve(msgvec)
292 int *msgvec;
283preserve(int *msgvec)
293{
294 int *ip, mesg;
295 struct message *mp;
296
297 if (edit) {
298 printf("Cannot \"preserve\" in edit mode\n");
299 return (1);
300 }

--- 6 unchanged lines hidden (view full) ---

307 }
308 return (0);
309}
310
311/*
312 * Mark all given messages as unread.
313 */
314int
284{
285 int *ip, mesg;
286 struct message *mp;
287
288 if (edit) {
289 printf("Cannot \"preserve\" in edit mode\n");
290 return (1);
291 }

--- 6 unchanged lines hidden (view full) ---

298 }
299 return (0);
300}
301
302/*
303 * Mark all given messages as unread.
304 */
305int
315unread(msgvec)
316 int msgvec[];
306unread(int msgvec[])
317{
318 int *ip;
319
320 for (ip = msgvec; *ip != 0; ip++) {
321 dot = &message[*ip-1];
322 dot->m_flag &= ~(MREAD|MTOUCH);
323 dot->m_flag |= MSTATUS;
324 }
325 return (0);
326}
327
328/*
329 * Print the size of each message.
330 */
331int
307{
308 int *ip;
309
310 for (ip = msgvec; *ip != 0; ip++) {
311 dot = &message[*ip-1];
312 dot->m_flag &= ~(MREAD|MTOUCH);
313 dot->m_flag |= MSTATUS;
314 }
315 return (0);
316}
317
318/*
319 * Print the size of each message.
320 */
321int
332messize(msgvec)
333 int *msgvec;
322messize(int *msgvec)
334{
335 struct message *mp;
336 int *ip, mesg;
337
338 for (ip = msgvec; *ip != 0; ip++) {
339 mesg = *ip;
340 mp = &message[mesg-1];
341 printf("%d: %ld/%ld\n", mesg, mp->m_lines, mp->m_size);
342 }
343 return (0);
344}
345
346/*
347 * Quit quickly. If we are sourcing, just pop the input level
348 * by returning an error.
349 */
350int
323{
324 struct message *mp;
325 int *ip, mesg;
326
327 for (ip = msgvec; *ip != 0; ip++) {
328 mesg = *ip;
329 mp = &message[mesg-1];
330 printf("%d: %ld/%ld\n", mesg, mp->m_lines, mp->m_size);
331 }
332 return (0);
333}
334
335/*
336 * Quit quickly. If we are sourcing, just pop the input level
337 * by returning an error.
338 */
339int
351rexit(e)
352 int e;
340rexit(int e __unused)
353{
354 if (sourcing)
355 return (1);
356 exit(0);
357 /*NOTREACHED*/
358}
359
360/*
361 * Set or display a variable value. Syntax is similar to that
362 * of csh.
363 */
364int
341{
342 if (sourcing)
343 return (1);
344 exit(0);
345 /*NOTREACHED*/
346}
347
348/*
349 * Set or display a variable value. Syntax is similar to that
350 * of csh.
351 */
352int
365set(arglist)
366 char **arglist;
353set(char **arglist)
367{
368 struct var *vp;
369 char *cp, *cp2;
370 char varbuf[BUFSIZ], **ap, **p;
371 int errs, h, s;
372
373 if (*arglist == NULL) {
374 for (h = 0, s = 1; h < HSHSIZE; h++)

--- 29 unchanged lines hidden (view full) ---

404 }
405 return (errs);
406}
407
408/*
409 * Unset a bunch of variable values.
410 */
411int
354{
355 struct var *vp;
356 char *cp, *cp2;
357 char varbuf[BUFSIZ], **ap, **p;
358 int errs, h, s;
359
360 if (*arglist == NULL) {
361 for (h = 0, s = 1; h < HSHSIZE; h++)

--- 29 unchanged lines hidden (view full) ---

391 }
392 return (errs);
393}
394
395/*
396 * Unset a bunch of variable values.
397 */
398int
412unset(arglist)
413 char **arglist;
399unset(char **arglist)
414{
415 struct var *vp, *vp2;
416 int errs, h;
417 char **ap;
418
419 errs = 0;
420 for (ap = arglist; *ap != NULL; ap++) {
421 if ((vp2 = lookup(*ap)) == NULL) {

--- 22 unchanged lines hidden (view full) ---

444 }
445 return (errs);
446}
447
448/*
449 * Put add users to a group.
450 */
451int
400{
401 struct var *vp, *vp2;
402 int errs, h;
403 char **ap;
404
405 errs = 0;
406 for (ap = arglist; *ap != NULL; ap++) {
407 if ((vp2 = lookup(*ap)) == NULL) {

--- 22 unchanged lines hidden (view full) ---

430 }
431 return (errs);
432}
433
434/*
435 * Put add users to a group.
436 */
437int
452group(argv)
453 char **argv;
438group(char **argv)
454{
455 struct grouphead *gh;
456 struct group *gp;
457 char **ap, *gname, **p;
458 int h, s;
459
460 if (*argv == NULL) {
461 for (h = 0, s = 1; h < HSHSIZE; h++)

--- 38 unchanged lines hidden (view full) ---

500 return (0);
501}
502
503/*
504 * Sort the passed string vecotor into ascending dictionary
505 * order.
506 */
507void
439{
440 struct grouphead *gh;
441 struct group *gp;
442 char **ap, *gname, **p;
443 int h, s;
444
445 if (*argv == NULL) {
446 for (h = 0, s = 1; h < HSHSIZE; h++)

--- 38 unchanged lines hidden (view full) ---

485 return (0);
486}
487
488/*
489 * Sort the passed string vecotor into ascending dictionary
490 * order.
491 */
492void
508sort(list)
509 char **list;
493sort(char **list)
510{
511 char **ap;
512
513 for (ap = list; *ap != NULL; ap++)
514 ;
515 if (ap-list < 2)
516 return;
517 qsort(list, ap-list, sizeof(*list), diction);
518}
519
520/*
521 * Do a dictionary order comparison of the arguments from
522 * qsort.
523 */
524int
494{
495 char **ap;
496
497 for (ap = list; *ap != NULL; ap++)
498 ;
499 if (ap-list < 2)
500 return;
501 qsort(list, ap-list, sizeof(*list), diction);
502}
503
504/*
505 * Do a dictionary order comparison of the arguments from
506 * qsort.
507 */
508int
525diction(a, b)
526 const void *a, *b;
509diction(const void *a, const void *b)
527{
528 return (strcmp(*(const char **)a, *(const char **)b));
529}
530
531/*
532 * The do nothing command for comments.
533 */
534
535/*ARGSUSED*/
536int
510{
511 return (strcmp(*(const char **)a, *(const char **)b));
512}
513
514/*
515 * The do nothing command for comments.
516 */
517
518/*ARGSUSED*/
519int
537null(e)
538 int e;
520null(int e __unused)
539{
540 return (0);
541}
542
543/*
544 * Change to another file. With no argument, print information about
545 * the current file.
546 */
547int
521{
522 return (0);
523}
524
525/*
526 * Change to another file. With no argument, print information about
527 * the current file.
528 */
529int
548file(argv)
549 char **argv;
530file(char **argv)
550{
551
552 if (argv[0] == NULL) {
553 newfileinfo(0);
554 return (0);
555 }
556 if (setfile(*argv) < 0)
557 return (1);
558 announce();
559 return (0);
560}
561
562/*
563 * Expand file names like echo
564 */
565int
531{
532
533 if (argv[0] == NULL) {
534 newfileinfo(0);
535 return (0);
536 }
537 if (setfile(*argv) < 0)
538 return (1);
539 announce();
540 return (0);
541}
542
543/*
544 * Expand file names like echo
545 */
546int
566echo(argv)
567 char **argv;
547echo(char **argv)
568{
569 char **ap, *cp;
570
571 for (ap = argv; *ap != NULL; ap++) {
572 cp = *ap;
573 if ((cp = expand(cp)) != NULL) {
574 if (ap != argv)
575 printf(" ");
576 printf("%s", cp);
577 }
578 }
579 printf("\n");
580 return (0);
581}
582
583int
548{
549 char **ap, *cp;
550
551 for (ap = argv; *ap != NULL; ap++) {
552 cp = *ap;
553 if ((cp = expand(cp)) != NULL) {
554 if (ap != argv)
555 printf(" ");
556 printf("%s", cp);
557 }
558 }
559 printf("\n");
560 return (0);
561}
562
563int
584Respond(msgvec)
585 int *msgvec;
564Respond(int *msgvec)
586{
587 if (value("Replyall") == NULL && value("flipr") == NULL)
588 return (doRespond(msgvec));
589 else
590 return (dorespond(msgvec));
591}
592
593/*
594 * Reply to a series of messages by simply mailing to the senders
595 * and not messing around with the To: and Cc: lists as in normal
596 * reply.
597 */
598int
565{
566 if (value("Replyall") == NULL && value("flipr") == NULL)
567 return (doRespond(msgvec));
568 else
569 return (dorespond(msgvec));
570}
571
572/*
573 * Reply to a series of messages by simply mailing to the senders
574 * and not messing around with the To: and Cc: lists as in normal
575 * reply.
576 */
577int
599doRespond(msgvec)
600 int msgvec[];
578doRespond(int msgvec[])
601{
602 struct header head;
603 struct message *mp;
604 int *ap;
605 char *cp, *mid;
606
607 head.h_to = NULL;
608 for (ap = msgvec; *ap != 0; ap++) {

--- 20 unchanged lines hidden (view full) ---

629 return (0);
630}
631
632/*
633 * Conditional commands. These allow one to parameterize one's
634 * .mailrc and do some things if sending, others if receiving.
635 */
636int
579{
580 struct header head;
581 struct message *mp;
582 int *ap;
583 char *cp, *mid;
584
585 head.h_to = NULL;
586 for (ap = msgvec; *ap != 0; ap++) {

--- 20 unchanged lines hidden (view full) ---

607 return (0);
608}
609
610/*
611 * Conditional commands. These allow one to parameterize one's
612 * .mailrc and do some things if sending, others if receiving.
613 */
614int
637ifcmd(argv)
638 char **argv;
615ifcmd(char **argv)
639{
640 char *cp;
641
642 if (cond != CANY) {
643 printf("Illegal nested \"if\"\n");
644 return (1);
645 }
646 cond = CANY;

--- 14 unchanged lines hidden (view full) ---

661 return (0);
662}
663
664/*
665 * Implement 'else'. This is pretty simple -- we just
666 * flip over the conditional flag.
667 */
668int
616{
617 char *cp;
618
619 if (cond != CANY) {
620 printf("Illegal nested \"if\"\n");
621 return (1);
622 }
623 cond = CANY;

--- 14 unchanged lines hidden (view full) ---

638 return (0);
639}
640
641/*
642 * Implement 'else'. This is pretty simple -- we just
643 * flip over the conditional flag.
644 */
645int
669elsecmd()
646elsecmd(void)
670{
671
672 switch (cond) {
673 case CANY:
674 printf("\"Else\" without matching \"if\"\n");
675 return (1);
676
677 case CSEND:

--- 11 unchanged lines hidden (view full) ---

689 }
690 return (0);
691}
692
693/*
694 * End of if statement. Just set cond back to anything.
695 */
696int
647{
648
649 switch (cond) {
650 case CANY:
651 printf("\"Else\" without matching \"if\"\n");
652 return (1);
653
654 case CSEND:

--- 11 unchanged lines hidden (view full) ---

666 }
667 return (0);
668}
669
670/*
671 * End of if statement. Just set cond back to anything.
672 */
673int
697endifcmd()
674endifcmd(void)
698{
699
700 if (cond == CANY) {
701 printf("\"Endif\" without matching \"if\"\n");
702 return (1);
703 }
704 cond = CANY;
705 return (0);
706}
707
708/*
709 * Set the list of alternate names.
710 */
711int
675{
676
677 if (cond == CANY) {
678 printf("\"Endif\" without matching \"if\"\n");
679 return (1);
680 }
681 cond = CANY;
682 return (0);
683}
684
685/*
686 * Set the list of alternate names.
687 */
688int
712alternates(namelist)
713 char **namelist;
689alternates(char **namelist)
714{
715 int c;
716 char **ap, **ap2, *cp;
717
718 c = argcount(namelist) + 1;
719 if (c == 1) {
720 if (altnames == 0)
721 return (0);

--- 16 unchanged lines hidden ---
690{
691 int c;
692 char **ap, **ap2, *cp;
693
694 c = argcount(namelist) + 1;
695 if (c == 1) {
696 if (altnames == 0)
697 return (0);

--- 16 unchanged lines hidden ---