xref: /csrg-svn/contrib/ed/bang.c (revision 58315)
157677Sbostic /*-
257677Sbostic  * Copyright (c) 1992 The Regents of the University of California.
357677Sbostic  * All rights reserved.
457677Sbostic  *
557677Sbostic  * This code is derived from software contributed to Berkeley by
657677Sbostic  * Rodney Ruddock of the University of Guelph.
757677Sbostic  *
857677Sbostic  * %sccs.include.redist.c%
957677Sbostic  */
1057677Sbostic 
1157677Sbostic #ifndef lint
12*58315Sbostic static char sccsid[] = "@(#)bang.c	5.3 (Berkeley) 02/28/93";
1357677Sbostic #endif /* not lint */
1457677Sbostic 
1557710Sbostic #include <sys/types.h>
1657710Sbostic 
17*58315Sbostic #include <limits.h>
1857710Sbostic #include <regex.h>
1957710Sbostic #include <setjmp.h>
2057710Sbostic #include <stdio.h>
2157710Sbostic #include <stdlib.h>
2257710Sbostic #include <string.h>
2357710Sbostic 
24*58315Sbostic #ifdef DBI
25*58315Sbostic #include <db.h>
26*58315Sbostic #endif
27*58315Sbostic 
2857677Sbostic #include "ed.h"
2957710Sbostic #include "extern.h"
3057677Sbostic 
3157677Sbostic /*
3257677Sbostic  * Execute a command in sh (and always sh). For those wondering the
3357677Sbostic  * proper name for '!' _is_ bang.
3457677Sbostic  */
3557677Sbostic 
3657677Sbostic void
3757677Sbostic bang(inputt, errnum)
3857710Sbostic 	FILE *inputt;
3957710Sbostic 	int *errnum;
4057677Sbostic {
4157710Sbostic 	static int l_cnt_last_pos;		/* "!!", l_shellcmd offset */
4257710Sbostic 	static char l_shellcmd[FILENAME_LEN];	/* "!!" */
4357710Sbostic 	int l_cnt = 0, l_esc = 0;
4457677Sbostic 
4557710Sbostic 	for (;;) {
4657710Sbostic 		ss = getchar();
4757710Sbostic 		if ((ss == '\\') && (l_esc == 0)) {
4857710Sbostic 			ss = getchar();
4957710Sbostic 			l_esc = 1;
5057710Sbostic 		} else
5157710Sbostic 			l_esc = 0;
5257710Sbostic 		if ((ss == '\n') || (ss == EOF)) {
5357710Sbostic 			if (l_cnt == 0) {
5457710Sbostic 				strcpy(help_msg, "no shell command given");
5557710Sbostic 				*errnum = -1;
5657710Sbostic 				ungetc('\n', inputt);
5757710Sbostic 				return;
5857710Sbostic 			}
5957710Sbostic 			l_shellcmd[l_cnt] = '\0';
6057710Sbostic 			break;
6157710Sbostic 		} else
6257710Sbostic 			if ((ss == '!') && (l_esc == 0))
6357710Sbostic 				l_cnt = l_cnt_last_pos;
6457710Sbostic 			else
6557710Sbostic 				if ((ss == '%') && (l_esc == 0)) {
6657710Sbostic 					l_shellcmd[l_cnt] = '\0';
67*58315Sbostic 					if (filename_current) {
68*58315Sbostic 						strcat(l_shellcmd,
69*58315Sbostic 						    filename_current);
70*58315Sbostic 						l_cnt =
71*58315Sbostic 						    l_cnt +
72*58315Sbostic 						    strlen(filename_current);
73*58315Sbostic 					}
7457710Sbostic 				} else
7557710Sbostic 					l_shellcmd[l_cnt++] = ss;
7657710Sbostic 		if (l_cnt >= FILENAME_LEN) {
7757710Sbostic 			strcpy(help_msg, "shell command too long");
7857710Sbostic 			*errnum = -1;
7957710Sbostic 			ungetc('\n', inputt);
8057710Sbostic 			return;
8157710Sbostic 		}
8257710Sbostic 	}
8357677Sbostic 
8457710Sbostic 	system(l_shellcmd);
8557710Sbostic 	if (explain_flag != 0)	/* for the -s option */
8657710Sbostic 		printf("!\n");
8757710Sbostic 	l_cnt_last_pos = l_cnt;
8857710Sbostic 	*errnum = 0;
8957710Sbostic }
90