xref: /original-bsd/contrib/ed/filename.c (revision 00534a39)
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[] = "@(#)filename.c	5.4 (Berkeley) 02/28/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 /*
33  * A central function for any command that has to deal with a filename
34  * (to be or not to be remembered).
35  */
36 char *
37 filename(inputt, errnum)
38 	FILE *inputt;
39 	int *errnum;
40 {
41 	register int l_cnt = 0;
42 	char *l_fname;
43 	int l_esc = 0, l_bang_flag = 0, l_len;
44 
45 	l_fname = calloc(FILENAME_LEN, sizeof(char));
46 	if (l_fname == NULL) {
47 		*errnum = -1;
48 		strcpy(help_msg, "out of memory error");
49 		return (NULL);
50 	}
51 	if ((ss = getc(inputt)) != ' ') {
52 		if (ss == '\n') {
53 			ungetc(ss, inputt);
54 			/*
55 			 * It's not really an error, but to flag remembered
56 			 * filename is to be used.
57 			 */
58 			*errnum = -2;
59 		} else {
60 			*errnum = -1;
61 			strcpy(help_msg,
62 			    "space required before filename given");
63 		}
64 		return (NULL);
65 	}
66 	while (ss = getc(inputt))
67 		if (ss != ' ') {
68 			ungetc(ss, inputt);
69 			break;
70 		}
71 	for (;;) {
72 		ss = getc(inputt);
73 		if ((ss == '\\') && (l_esc == 0)) {
74 			ss = getchar();
75 			l_esc = 1;
76 		} else
77 			l_esc = 0;
78 		if ((ss == '\n') || (ss == EOF)) {
79 			l_fname[l_cnt] = '\0';
80 			break;
81 		} else
82 			if ((ss == '!') && (l_esc == 0))
83 				l_bang_flag = 1;
84 			else
85 				if ((ss != ' ') || (l_bang_flag))
86 					l_fname[l_cnt++] = ss;
87 				else {
88 					*errnum = -1;
89 					return (NULL);
90 				}
91 
92 		if (l_cnt >= FILENAME_LEN) {
93 			strcpy(help_msg, "filename+path length too long");
94 			*errnum = -1;
95 			ungetc('\n', inputt);
96 			return (NULL);
97 		}
98 	}
99 
100 	if (l_bang_flag == 1) {	/* user wants the name from a sh command */
101 		FILE   *namestream, *popen();
102 
103 		if (l_fname[0] == '\0') {
104 			strcpy(help_msg, "no command given");
105 			*errnum = -1;
106 			return (NULL);
107 		}
108 		if (((namestream = popen(l_fname, "r")) == NULL) ||
109 		    ((fgets(l_fname, FILENAME_LEN - 1, namestream)) == NULL)) {
110 			strcpy(help_msg, "error executing command");
111 			*errnum = -1;
112 			if (namestream != NULL)
113 				pclose(namestream);
114 			ungetc('\n', inputt);
115 			return (NULL);
116 		}
117 		l_len = strlen(l_fname) - 1;
118 		if (l_fname[l_len] == '\n')
119 			l_fname[l_len] = '\0';
120 		pclose(namestream);
121 	} else
122 		if (l_fname[0] == '\0') {
123 			sigspecial++;
124 			strcpy(l_fname, filename_current);
125 			sigspecial--;
126 			if (sigint_flag && (!sigspecial))
127 				SIGINT_ACTION;
128 		}
129 	*errnum = 1;
130 	return (l_fname);
131 }
132