1 /* Copyright (c) 1979 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)GETNAME.c 1.3 03/07/81";
4 
5 #include "h00vars.h"
6 #include "h01errs.h"
7 
8 /*
9  * GETNAME - activate a file
10  *
11  * takes a name, name length, element size, and variable
12  * level and returns a pointer to a file structure.
13  *
14  * a new file structure is initialized if necessary.
15  * temporary names are generated, and given
16  * names are blank trimmed.
17  */
18 
19 struct iorec *
20 GETNAME(filep, name, namlim, datasize)
21 
22 	register struct iorec	*filep;
23 	char			*name;
24 	long			namlim;
25 	long			datasize;
26 {
27 	int		maxnamlen = namlim;
28 	struct iorec	*prev;
29 	struct iorec	*next;
30 	register int	cnt;
31 	struct iorec	locvar;
32 	extern char	*mktemp();
33 
34 	if (filep->fblk >= MAXFILES || _actfile[filep->fblk] != filep) {
35 		/*
36 		 * initialize a new filerecord
37 		 */
38 		filep->funit = 0;
39 		if (datasize == 0) {
40 			filep->funit |= FTEXT;
41 			datasize = 1;
42 		}
43 		filep->fsize = datasize;
44 		filep->fbuf = 0;
45 		filep->lcount = 0;
46 		filep->llimit = 0x7fffffff;
47 		filep->fileptr = &filep->window[0];
48 		/*
49 		 * check to see if file is global, or allocated in
50 		 * the stack by checking its address against the
51 		 * address of one of our routine's local variables.
52 		 */
53 		if (filep < &locvar)
54 			filep->flev = GLVL;
55 		else
56 			filep->flev = filep;
57 		do {
58 			if (++_filefre == MAXFILES)
59 				_filefre = PREDEF + 1;
60 		} while (_actfile[_filefre] != FILNIL);
61 		filep->fblk = _filefre;
62 		_actfile[_filefre] = filep;
63 		/*
64 		 * link the newrecord into the file chain
65 		 */
66 		prev = (struct iorec *)&_fchain;
67 		next = _fchain.fchain;
68 		while (filep->flev > next->flev) {
69 			prev = next;
70 			next = next->fchain;
71 		}
72 		filep->fchain = next;
73 		prev->fchain = filep;
74 	} else {
75 		if ((filep->funit & FDEF) == 0) {
76 			/*
77 			 * have a previous buffer, close associated file
78 			 */
79 			if (filep->fblk > PREDEF) {
80 				fflush(filep->fbuf);
81 				setbuf(filep->fbuf, NULL);
82 			}
83 			fclose(filep->fbuf);
84 			if (ferror(filep->fbuf)) {
85 				ERROR(ECLOSE, filep->pfname);
86 				return;
87 			}
88 			/*
89 			 * renamed temporary files are discarded
90 			 */
91 			if ((filep->funit & TEMP) &&
92 			    (name != NULL) &&
93 			    (unlink(filep->pfname))) {
94 				ERROR(EREMOVE, filep->pfname);
95 				return;
96 			}
97 		}
98 		filep->funit &= (TEMP | FTEXT);
99 	}
100 	/*
101 	 * get the filename associated with the buffer
102 	 */
103 	if (name == NULL) {
104 		if (*filep->fname != NULL) {
105 			return(filep);
106 		}
107 		/*
108 		 * no name given and no previous name, so generate
109 		 * a new one of the form tmp.xxxxxx
110 		 */
111 		filep->funit |= TEMP;
112 		name = mktemp("tmp.XXXXXX");
113 		maxnamlen = 10;
114 	} else {
115 		/*
116 		 * trim trailing blanks, and insure that the name
117 		 * will fit into the file structure
118 		 */
119 		for (cnt = 0; cnt < maxnamlen; cnt++)
120 			if (name[cnt] == '\0' || name[cnt] == ' ')
121 				break;
122 		if (cnt >= NAMSIZ) {
123 			ERROR(ENAMESIZE, name);
124 			return;
125 		}
126 		maxnamlen = cnt;
127 		filep->funit &= ~TEMP;
128 	}
129 	/*
130 	 * put the new name into the structure
131 	 */
132 	for (cnt = 0; cnt < maxnamlen; cnt++)
133 		filep->fname[cnt] = name[cnt];
134 	filep->fname[cnt] = '\0';
135 	filep->pfname = &filep->fname[0];
136 	return(filep);
137 }
138