1 /*- 2 * Copyright (c) 1992 The Regents of the University of California. 3 * 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 5.6 (Berkeley) 04/30/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 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