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