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 --- |