157685Sbostic /*- 257685Sbostic * Copyright (c) 1992 The Regents of the University of California. 357685Sbostic * All rights reserved. 457685Sbostic * 557685Sbostic * This code is derived from software contributed to Berkeley by 657685Sbostic * Rodney Ruddock of the University of Guelph. 757685Sbostic * 857685Sbostic * %sccs.include.redist.c% 957685Sbostic */ 1057685Sbostic 1157685Sbostic #ifndef lint 12*58316Sbostic static char sccsid[] = "@(#)filename.c 5.4 (Berkeley) 02/28/93"; 1357685Sbostic #endif /* not lint */ 1457685Sbostic 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 2857685Sbostic #include "ed.h" 2957710Sbostic #include "extern.h" 3057685Sbostic 3158315Sbostic 3257685Sbostic /* 3357685Sbostic * A central function for any command that has to deal with a filename 3457685Sbostic * (to be or not to be remembered). 3557685Sbostic */ 3657710Sbostic char * 3757710Sbostic filename(inputt, errnum) 3857710Sbostic FILE *inputt; 3957710Sbostic int *errnum; 4057685Sbostic { 4157710Sbostic register int l_cnt = 0; 4257710Sbostic char *l_fname; 4357710Sbostic int l_esc = 0, l_bang_flag = 0, l_len; 4457685Sbostic 4557710Sbostic l_fname = calloc(FILENAME_LEN, sizeof(char)); 4657710Sbostic if (l_fname == NULL) { 4757710Sbostic *errnum = -1; 4857710Sbostic strcpy(help_msg, "out of memory error"); 4957710Sbostic return (NULL); 5057710Sbostic } 5157710Sbostic if ((ss = getc(inputt)) != ' ') { 5257710Sbostic if (ss == '\n') { 5357710Sbostic ungetc(ss, inputt); 5457710Sbostic /* 5557710Sbostic * It's not really an error, but to flag remembered 5657710Sbostic * filename is to be used. 5757710Sbostic */ 5857710Sbostic *errnum = -2; 5957710Sbostic } else { 6057710Sbostic *errnum = -1; 6157710Sbostic strcpy(help_msg, 6257710Sbostic "space required before filename given"); 6357710Sbostic } 6457710Sbostic return (NULL); 6557710Sbostic } 6657710Sbostic while (ss = getc(inputt)) 6757710Sbostic if (ss != ' ') { 6857710Sbostic ungetc(ss, inputt); 6957710Sbostic break; 7057710Sbostic } 7157710Sbostic for (;;) { 7257710Sbostic ss = getc(inputt); 7357710Sbostic if ((ss == '\\') && (l_esc == 0)) { 7457710Sbostic ss = getchar(); 7557710Sbostic l_esc = 1; 7657710Sbostic } else 7757710Sbostic l_esc = 0; 7857710Sbostic if ((ss == '\n') || (ss == EOF)) { 7957710Sbostic l_fname[l_cnt] = '\0'; 8057710Sbostic break; 8157710Sbostic } else 8257710Sbostic if ((ss == '!') && (l_esc == 0)) 8357710Sbostic l_bang_flag = 1; 8457710Sbostic else 8558315Sbostic if ((ss != ' ') || (l_bang_flag)) 8657710Sbostic l_fname[l_cnt++] = ss; 8758315Sbostic else { 8858315Sbostic *errnum = -1; 89*58316Sbostic return (NULL); 9058315Sbostic } 9157685Sbostic 9257710Sbostic if (l_cnt >= FILENAME_LEN) { 9357710Sbostic strcpy(help_msg, "filename+path length too long"); 9457710Sbostic *errnum = -1; 9557710Sbostic ungetc('\n', inputt); 9657710Sbostic return (NULL); 9757710Sbostic } 9857710Sbostic } 9957685Sbostic 10057710Sbostic if (l_bang_flag == 1) { /* user wants the name from a sh command */ 10157710Sbostic FILE *namestream, *popen(); 10257685Sbostic 10357710Sbostic if (l_fname[0] == '\0') { 10457710Sbostic strcpy(help_msg, "no command given"); 10557710Sbostic *errnum = -1; 10657710Sbostic return (NULL); 10757710Sbostic } 10857710Sbostic if (((namestream = popen(l_fname, "r")) == NULL) || 10957710Sbostic ((fgets(l_fname, FILENAME_LEN - 1, namestream)) == NULL)) { 11057710Sbostic strcpy(help_msg, "error executing command"); 11157710Sbostic *errnum = -1; 11257710Sbostic if (namestream != NULL) 11357710Sbostic pclose(namestream); 11458315Sbostic ungetc('\n', inputt); 11557710Sbostic return (NULL); 11657710Sbostic } 11757710Sbostic l_len = strlen(l_fname) - 1; 11857710Sbostic if (l_fname[l_len] == '\n') 11957710Sbostic l_fname[l_len] = '\0'; 12057710Sbostic pclose(namestream); 12157710Sbostic } else 12258315Sbostic if (l_fname[0] == '\0') { 12358315Sbostic sigspecial++; 12457710Sbostic strcpy(l_fname, filename_current); 12558315Sbostic sigspecial--; 12658315Sbostic if (sigint_flag && (!sigspecial)) 12758315Sbostic SIGINT_ACTION; 12858315Sbostic } 12958315Sbostic *errnum = 1; 13057710Sbostic return (l_fname); 13157710Sbostic } 132