1 /*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. 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 8.1 (Berkeley) 05/31/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
bang(inputt,errnum)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