xref: /csrg-svn/contrib/ed/bang.c (revision 59475)
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*59475Sbostic static char sccsid[] = "@(#)bang.c	5.5 (Berkeley) 04/28/93";
1357677Sbostic #endif /* not lint */
1457677Sbostic 
1557710Sbostic #include <sys/types.h>
1657710Sbostic 
1758315Sbostic #include <limits.h>
1857710Sbostic #include <regex.h>
1957710Sbostic #include <setjmp.h>
2057710Sbostic #include <stdio.h>
2157710Sbostic #include <stdlib.h>
2257710Sbostic #include <string.h>
2357710Sbostic 
2458315Sbostic #ifdef DBI
2558315Sbostic #include <db.h>
2658315Sbostic #endif
2758315Sbostic 
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
62*59475Sbostic 			if ((ss == '!') && (l_esc == 0)) {
6357710Sbostic 				l_cnt = l_cnt_last_pos;
64*59475Sbostic 				printf("%s\n", l_shellcmd);
65*59475Sbostic 			}
6657710Sbostic 			else
6757710Sbostic 				if ((ss == '%') && (l_esc == 0)) {
6857710Sbostic 					l_shellcmd[l_cnt] = '\0';
6958315Sbostic 					if (filename_current) {
7058315Sbostic 						strcat(l_shellcmd,
7158315Sbostic 						    filename_current);
7258315Sbostic 						l_cnt =
7358315Sbostic 						    l_cnt +
7458315Sbostic 						    strlen(filename_current);
7558315Sbostic 					}
7657710Sbostic 				} else
7757710Sbostic 					l_shellcmd[l_cnt++] = ss;
7857710Sbostic 		if (l_cnt >= FILENAME_LEN) {
7957710Sbostic 			strcpy(help_msg, "shell command too long");
8057710Sbostic 			*errnum = -1;
8157710Sbostic 			ungetc('\n', inputt);
8257710Sbostic 			return;
8357710Sbostic 		}
8457710Sbostic 	}
8557677Sbostic 
8657710Sbostic 	system(l_shellcmd);
8758710Sbostic 	if (explain_flag > 0)	/* for the -s option */
8857710Sbostic 		printf("!\n");
8957710Sbostic 	l_cnt_last_pos = l_cnt;
9057710Sbostic 	*errnum = 0;
9157710Sbostic }
92