xref: /csrg-svn/contrib/ed/bang.c (revision 60663)
157677Sbostic /*-
2*60663Sbostic  * Copyright (c) 1992, 1993
3*60663Sbostic  *	The Regents of the University of California.  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*60663Sbostic static char sccsid[] = "@(#)bang.c	8.1 (Berkeley) 05/31/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
bang(inputt,errnum)3757677Sbostic bang(inputt, errnum)
3857710Sbostic 	FILE *inputt;
3957710Sbostic 	int *errnum;
4057677Sbostic {
4159558Sbostic 	static int l_cnt_last_pos=0;		/* "!!", l_shellcmd offset */
4257710Sbostic 	static char l_shellcmd[FILENAME_LEN];	/* "!!" */
4359558Sbostic 	static char l_shellcmd2[FILENAME_LEN];	/* "!!" */
4459558Sbostic 	int l_cnt = 0, l_esc=0, l_flag=0;
4557677Sbostic 
4659558Sbostic 	memcpy(l_shellcmd, l_shellcmd2, FILENAME_LEN);
4759558Sbostic 
4857710Sbostic 	for (;;) {
4959558Sbostic 		ss = getc(inputt);
5059558Sbostic 		l_esc = 0;
5159558Sbostic 		if (ss == '\\') {
5259558Sbostic 			ss = getc(inputt);
5357710Sbostic 			l_esc = 1;
5459558Sbostic 		}
5559558Sbostic 		if (((!l_esc) && (ss == '\n')) || (ss == EOF)) {
5657710Sbostic 			l_shellcmd[l_cnt] = '\0';
5757710Sbostic 			break;
5857710Sbostic 		} else
5959558Sbostic 			if ((ss == '!') && (l_cnt == 0) && (l_esc == 0)) {
6059558Sbostic 				if (l_cnt_last_pos == 0) {
6159558Sbostic 					strcpy(help_msg,
6259558Sbostic 					    "no remembered command");
6359558Sbostic 					*errnum = -1;
6459558Sbostic 					return;
6559558Sbostic 				}
6657710Sbostic 				l_cnt = l_cnt_last_pos;
6759558Sbostic 				l_flag = 1;
6859475Sbostic 			}
6957710Sbostic 			else
7057710Sbostic 				if ((ss == '%') && (l_esc == 0)) {
7158315Sbostic 					if (filename_current) {
7259558Sbostic 						l_shellcmd[l_cnt] = '\0';
7358315Sbostic 						strcat(l_shellcmd,
7458315Sbostic 						    filename_current);
7558315Sbostic 						l_cnt =
7658315Sbostic 						    l_cnt +
7759558Sbostic 						    strlen(filename_current);
7858315Sbostic 					}
7959558Sbostic 					else {
8059558Sbostic 						strcpy(help_msg,
8159558Sbostic 						    "no current filename");
8259558Sbostic 						*errnum = -1;
8359558Sbostic 						return;
8459558Sbostic 					}
8557710Sbostic 				} else
8657710Sbostic 					l_shellcmd[l_cnt++] = ss;
8757710Sbostic 		if (l_cnt >= FILENAME_LEN) {
8857710Sbostic 			strcpy(help_msg, "shell command too long");
8957710Sbostic 			*errnum = -1;
9057710Sbostic 			return;
9157710Sbostic 		}
9257710Sbostic 	}
9357677Sbostic 
9459558Sbostic 	if (l_flag)
9559558Sbostic 		printf("%s\n", l_shellcmd);
9657710Sbostic 	system(l_shellcmd);
9758710Sbostic 	if (explain_flag > 0)	/* for the -s option */
9857710Sbostic 		printf("!\n");
9957710Sbostic 	l_cnt_last_pos = l_cnt;
10059558Sbostic 	memcpy(l_shellcmd2, l_shellcmd, FILENAME_LEN);
10157710Sbostic 	*errnum = 0;
10257710Sbostic }
103