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