xref: /original-bsd/contrib/ed/filename.c (revision df23cbe6)
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.2 (Berkeley) 01/23/93";
13 #endif /* not lint */
14 
15 #include <sys/types.h>
16 
17 #include <db.h>
18 #include <regex.h>
19 #include <setjmp.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "ed.h"
25 #include "extern.h"
26 
27 /*
28  * A central function for any command that has to deal with a filename
29  * (to be or not to be remembered).
30  */
31 char *
32 filename(inputt, errnum)
33 	FILE *inputt;
34 	int *errnum;
35 {
36 	register int l_cnt = 0;
37 	char *l_fname;
38 	int l_esc = 0, l_bang_flag = 0, l_len;
39 
40 	l_fname = calloc(FILENAME_LEN, sizeof(char));
41 	if (l_fname == NULL) {
42 		*errnum = -1;
43 		strcpy(help_msg, "out of memory error");
44 		return (NULL);
45 	}
46 	if ((ss = getc(inputt)) != ' ') {
47 		if (ss == '\n') {
48 			ungetc(ss, inputt);
49 			/*
50 			 * It's not really an error, but to flag remembered
51 			 * filename is to be used.
52 			 */
53 			*errnum = -2;
54 		} else {
55 			*errnum = -1;
56 			strcpy(help_msg,
57 			    "space required before filename given");
58 		}
59 		return (NULL);
60 	}
61 	while (ss = getc(inputt))
62 		if (ss != ' ') {
63 			ungetc(ss, inputt);
64 			break;
65 		}
66 	for (;;) {
67 		ss = getc(inputt);
68 		if ((ss == '\\') && (l_esc == 0)) {
69 			ss = getchar();
70 			l_esc = 1;
71 		} else
72 			l_esc = 0;
73 		if ((ss == '\n') || (ss == EOF)) {
74 			l_fname[l_cnt] = '\0';
75 			break;
76 		} else
77 			if ((ss == '!') && (l_esc == 0))
78 				l_bang_flag = 1;
79 			else
80 				if (ss != ' ')
81 					l_fname[l_cnt++] = ss;
82 				else
83 					continue;
84 
85 		if (l_cnt >= FILENAME_LEN) {
86 			strcpy(help_msg, "filename+path length too long");
87 			*errnum = -1;
88 			ungetc('\n', inputt);
89 			return (NULL);
90 		}
91 	}
92 
93 	if (l_bang_flag == 1) {	/* user wants the name from a sh command */
94 		FILE   *namestream, *popen();
95 
96 		if (l_fname[0] == '\0') {
97 			strcpy(help_msg, "no command given");
98 			*errnum = -1;
99 			return (NULL);
100 		}
101 		if (((namestream = popen(l_fname, "r")) == NULL) ||
102 		    ((fgets(l_fname, FILENAME_LEN - 1, namestream)) == NULL)) {
103 			strcpy(help_msg, "error executing command");
104 			*errnum = -1;
105 			if (namestream != NULL)
106 				pclose(namestream);
107 			return (NULL);
108 		}
109 		l_len = strlen(l_fname) - 1;
110 		if (l_fname[l_len] == '\n')
111 			l_fname[l_len] = '\0';
112 		pclose(namestream);
113 	} else
114 		if (l_fname[0] == '\0')
115 			strcpy(l_fname, filename_current);
116 		else
117 			*errnum = 1;
118 	return (l_fname);
119 }
120