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*59558Sbostic static char sccsid[] = "@(#)bang.c 5.6 (Berkeley) 04/30/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 { 41*59558Sbostic static int l_cnt_last_pos=0; /* "!!", l_shellcmd offset */ 4257710Sbostic static char l_shellcmd[FILENAME_LEN]; /* "!!" */ 43*59558Sbostic static char l_shellcmd2[FILENAME_LEN]; /* "!!" */ 44*59558Sbostic int l_cnt = 0, l_esc=0, l_flag=0; 4557677Sbostic 46*59558Sbostic memcpy(l_shellcmd, l_shellcmd2, FILENAME_LEN); 47*59558Sbostic 4857710Sbostic for (;;) { 49*59558Sbostic ss = getc(inputt); 50*59558Sbostic l_esc = 0; 51*59558Sbostic if (ss == '\\') { 52*59558Sbostic ss = getc(inputt); 5357710Sbostic l_esc = 1; 54*59558Sbostic } 55*59558Sbostic if (((!l_esc) && (ss == '\n')) || (ss == EOF)) { 5657710Sbostic l_shellcmd[l_cnt] = '\0'; 5757710Sbostic break; 5857710Sbostic } else 59*59558Sbostic if ((ss == '!') && (l_cnt == 0) && (l_esc == 0)) { 60*59558Sbostic if (l_cnt_last_pos == 0) { 61*59558Sbostic strcpy(help_msg, 62*59558Sbostic "no remembered command"); 63*59558Sbostic *errnum = -1; 64*59558Sbostic return; 65*59558Sbostic } 6657710Sbostic l_cnt = l_cnt_last_pos; 67*59558Sbostic l_flag = 1; 6859475Sbostic } 6957710Sbostic else 7057710Sbostic if ((ss == '%') && (l_esc == 0)) { 7158315Sbostic if (filename_current) { 72*59558Sbostic l_shellcmd[l_cnt] = '\0'; 7358315Sbostic strcat(l_shellcmd, 7458315Sbostic filename_current); 7558315Sbostic l_cnt = 7658315Sbostic l_cnt + 77*59558Sbostic strlen(filename_current); 7858315Sbostic } 79*59558Sbostic else { 80*59558Sbostic strcpy(help_msg, 81*59558Sbostic "no current filename"); 82*59558Sbostic *errnum = -1; 83*59558Sbostic return; 84*59558Sbostic } 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 94*59558Sbostic if (l_flag) 95*59558Sbostic 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; 100*59558Sbostic memcpy(l_shellcmd2, l_shellcmd, FILENAME_LEN); 10157710Sbostic *errnum = 0; 10257710Sbostic } 103