xref: /original-bsd/contrib/ed/bang.c (revision 70c898fa)
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.6 (Berkeley) 04/30/93";
13 #endif /* not lint */
14 
15 #include <sys/types.h>
16 
17 #include <limits.h>
18 #include <regex.h>
19 #include <setjmp.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #ifdef DBI
25 #include <db.h>
26 #endif
27 
28 #include "ed.h"
29 #include "extern.h"
30 
31 /*
32  * Execute a command in sh (and always sh). For those wondering the
33  * proper name for '!' _is_ bang.
34  */
35 
36 void
37 bang(inputt, errnum)
38 	FILE *inputt;
39 	int *errnum;
40 {
41 	static int l_cnt_last_pos=0;		/* "!!", l_shellcmd offset */
42 	static char l_shellcmd[FILENAME_LEN];	/* "!!" */
43 	static char l_shellcmd2[FILENAME_LEN];	/* "!!" */
44 	int l_cnt = 0, l_esc=0, l_flag=0;
45 
46 	memcpy(l_shellcmd, l_shellcmd2, FILENAME_LEN);
47 
48 	for (;;) {
49 		ss = getc(inputt);
50 		l_esc = 0;
51 		if (ss == '\\') {
52 			ss = getc(inputt);
53 			l_esc = 1;
54 		}
55 		if (((!l_esc) && (ss == '\n')) || (ss == EOF)) {
56 			l_shellcmd[l_cnt] = '\0';
57 			break;
58 		} else
59 			if ((ss == '!') && (l_cnt == 0) && (l_esc == 0)) {
60 				if (l_cnt_last_pos == 0) {
61 					strcpy(help_msg,
62 					    "no remembered command");
63 					*errnum = -1;
64 					return;
65 				}
66 				l_cnt = l_cnt_last_pos;
67 				l_flag = 1;
68 			}
69 			else
70 				if ((ss == '%') && (l_esc == 0)) {
71 					if (filename_current) {
72 						l_shellcmd[l_cnt] = '\0';
73 						strcat(l_shellcmd,
74 						    filename_current);
75 						l_cnt =
76 						    l_cnt +
77 						    strlen(filename_current);
78 					}
79 					else {
80 						strcpy(help_msg,
81 						    "no current filename");
82 						*errnum = -1;
83 						return;
84 					}
85 				} else
86 					l_shellcmd[l_cnt++] = ss;
87 		if (l_cnt >= FILENAME_LEN) {
88 			strcpy(help_msg, "shell command too long");
89 			*errnum = -1;
90 			return;
91 		}
92 	}
93 
94 	if (l_flag)
95 		printf("%s\n", l_shellcmd);
96 	system(l_shellcmd);
97 	if (explain_flag > 0)	/* for the -s option */
98 		printf("!\n");
99 	l_cnt_last_pos = l_cnt;
100 	memcpy(l_shellcmd2, l_shellcmd, FILENAME_LEN);
101 	*errnum = 0;
102 }
103