xref: /csrg-svn/contrib/ed/bang.c (revision 57710)
1 /*-
2  * Copyright (c) 1992 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Rodney Ruddock of the University of Guelph.
7  *
8  * %sccs.include.redist.c%
9  */
10 
11 #ifndef lint
12 static char sccsid[] = "@(#)bang.c	5.2 (Berkeley) 01/23/93";
13 #endif /* not lint */
14 
15 #include <sys/types.h>
16 
17 #include <db.h>
18 #include <regex.h>
19 #include <setjmp.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "ed.h"
25 #include "extern.h"
26 
27 /*
28  * Execute a command in sh (and always sh). For those wondering the
29  * proper name for '!' _is_ bang.
30  */
31 
32 void
33 bang(inputt, errnum)
34 	FILE *inputt;
35 	int *errnum;
36 {
37 	static int l_cnt_last_pos;		/* "!!", l_shellcmd offset */
38 	static char l_shellcmd[FILENAME_LEN];	/* "!!" */
39 	int l_cnt = 0, l_esc = 0;
40 
41 	for (;;) {
42 		if (sigint_flag)
43 			SIGINT_ACTION;
44 		ss = getchar();
45 		if ((ss == '\\') && (l_esc == 0)) {
46 			ss = getchar();
47 			l_esc = 1;
48 		} else
49 			l_esc = 0;
50 		if ((ss == '\n') || (ss == EOF)) {
51 			if (l_cnt == 0) {
52 				strcpy(help_msg, "no shell command given");
53 				*errnum = -1;
54 				ungetc('\n', inputt);
55 				return;
56 			}
57 			l_shellcmd[l_cnt] = '\0';
58 			break;
59 		} else
60 			if ((ss == '!') && (l_esc == 0))
61 				l_cnt = l_cnt_last_pos;
62 			else
63 				if ((ss == '%') && (l_esc == 0)) {
64 					l_shellcmd[l_cnt] = '\0';
65 					strcat(l_shellcmd, filename_current);
66 					l_cnt =
67 					    l_cnt + strlen(filename_current);
68 				} else
69 					l_shellcmd[l_cnt++] = ss;
70 		if (l_cnt >= FILENAME_LEN) {
71 			strcpy(help_msg, "shell command too long");
72 			*errnum = -1;
73 			ungetc('\n', inputt);
74 			return;
75 		}
76 	}
77 
78 	system(l_shellcmd);
79 	if (explain_flag != 0)	/* for the -s option */
80 		printf("!\n");
81 	l_cnt_last_pos = l_cnt;
82 	*errnum = 0;
83 }
84