11656Smckusick /* Copyright (c) 1979 Regents of the University of California */
21656Smckusick 
3*5058Smckusic static char sccsid[] = "@(#)GETNAME.c 1.8 11/23/81";
41656Smckusick 
51656Smckusick #include "h00vars.h"
61656Smckusick 
71656Smckusick /*
81656Smckusick  * GETNAME - activate a file
91656Smckusick  *
101656Smckusick  * takes a name, name length, element size, and variable
111656Smckusick  * level and returns a pointer to a file structure.
121656Smckusick  *
131656Smckusick  * a new file structure is initialized if necessary.
141656Smckusick  * temporary names are generated, and given
151656Smckusick  * names are blank trimmed.
161656Smckusick  */
171656Smckusick 
18*5058Smckusic static char *tmpname = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
19*5058Smckusic 
201656Smckusick struct iorec *
213006Smckusic GETNAME(filep, name, namlim, datasize)
221656Smckusick 
231656Smckusick 	register struct iorec	*filep;
241656Smckusick 	char			*name;
253006Smckusic 	long			namlim;
263006Smckusic 	long			datasize;
271656Smckusick {
283006Smckusic 	int		maxnamlen = namlim;
291656Smckusick 	struct iorec	*prev;
301656Smckusick 	struct iorec	*next;
311656Smckusick 	register int	cnt;
321656Smckusick 	struct iorec	locvar;
331656Smckusick 
341656Smckusick 	if (filep->fblk >= MAXFILES || _actfile[filep->fblk] != filep) {
351656Smckusick 		/*
361656Smckusick 		 * initialize a new filerecord
371656Smckusick 		 */
381656Smckusick 		filep->funit = 0;
391656Smckusick 		if (datasize == 0) {
401656Smckusick 			filep->funit |= FTEXT;
411656Smckusick 			datasize = 1;
421656Smckusick 		}
431656Smckusick 		filep->fsize = datasize;
441656Smckusick 		filep->fbuf = 0;
451656Smckusick 		filep->lcount = 0;
461656Smckusick 		filep->llimit = 0x7fffffff;
471656Smckusick 		filep->fileptr = &filep->window[0];
481656Smckusick 		/*
491656Smckusick 		 * check to see if file is global, or allocated in
501656Smckusick 		 * the stack by checking its address against the
511656Smckusick 		 * address of one of our routine's local variables.
521656Smckusick 		 */
531656Smckusick 		if (filep < &locvar)
541656Smckusick 			filep->flev = GLVL;
551656Smckusick 		else
561656Smckusick 			filep->flev = filep;
57*5058Smckusic 		for (_filefre++; _filefre < MAXFILES; _filefre++)
58*5058Smckusic 			if (_actfile[_filefre] == FILNIL)
59*5058Smckusic 				goto gotone;
60*5058Smckusic 		for (_filefre = PREDEF + 1; _filefre < MAXFILES; _filefre++)
61*5058Smckusic 			if (_actfile[_filefre] == FILNIL)
62*5058Smckusic 				goto gotone;
63*5058Smckusic 		ERROR("File table overflow\n");
64*5058Smckusic 		return;
65*5058Smckusic gotone:
661656Smckusick 		filep->fblk = _filefre;
671656Smckusick 		_actfile[_filefre] = filep;
681656Smckusick 		/*
691656Smckusick 		 * link the newrecord into the file chain
701656Smckusick 		 */
711656Smckusick 		prev = (struct iorec *)&_fchain;
721656Smckusick 		next = _fchain.fchain;
731656Smckusick 		while (filep->flev > next->flev) {
741656Smckusick 			prev = next;
751656Smckusick 			next = next->fchain;
761656Smckusick 		}
771656Smckusick 		filep->fchain = next;
781656Smckusick 		prev->fchain = filep;
791656Smckusick 	} else {
803860Smckusic 		if ((filep->funit & FDEF) == 0 && filep->fbuf != NULL) {
811656Smckusick 			/*
821656Smckusick 			 * have a previous buffer, close associated file
831656Smckusick 			 */
842107Smckusic 			if (filep->fblk > PREDEF) {
852107Smckusic 				fflush(filep->fbuf);
862107Smckusic 				setbuf(filep->fbuf, NULL);
872107Smckusic 			}
881656Smckusick 			fclose(filep->fbuf);
891656Smckusick 			if (ferror(filep->fbuf)) {
903867Smckusic 				ERROR("%s: Close failed\n", filep->pfname);
911656Smckusick 				return;
921656Smckusick 			}
931656Smckusick 			/*
941656Smckusick 			 * renamed temporary files are discarded
951656Smckusick 			 */
963860Smckusic 			if ((filep->funit & TEMP) && name != NULL) {
973860Smckusic 			    	if (unlink(filep->pfname)) {
983867Smckusic 					PERROR("Could not remove ",
993867Smckusic 						filep->pfname);
1003860Smckusic 					return;
1013860Smckusic 				}
1021656Smckusick 			}
1031656Smckusick 		}
1043006Smckusic 		filep->funit &= (TEMP | FTEXT);
1051656Smckusick 	}
1061656Smckusick 	/*
1071656Smckusick 	 * get the filename associated with the buffer
1081656Smckusick 	 */
1091656Smckusick 	if (name == NULL) {
1101656Smckusick 		if (*filep->fname != NULL) {
1111656Smckusick 			return(filep);
1121656Smckusick 		}
1131656Smckusick 		/*
1141656Smckusick 		 * no name given and no previous name, so generate
1153860Smckusic 		 * a new one of the form #tmp.xxxxxx
1161656Smckusick 		 */
1171656Smckusick 		filep->funit |= TEMP;
118*5058Smckusic 		sprintf(filep->fname, "#tmp.%c%d", tmpname[filep->fblk],
1195023Smckusic 		    getpid());
1203662Smckusic 		filep->pfname = &filep->fname[0];
1213662Smckusic 		return(filep);
1221656Smckusick 	}
1231656Smckusick 	/*
1243662Smckusic 	 * trim trailing blanks, and insure that the name
1253662Smckusic 	 * will fit into the file structure
1263662Smckusic 	 */
1273662Smckusic 	for (cnt = 0; cnt < maxnamlen; cnt++)
1283662Smckusic 		if (name[cnt] == '\0' || name[cnt] == ' ')
1293662Smckusic 			break;
1303662Smckusic 	if (cnt >= NAMSIZ) {
1313867Smckusic 		ERROR("%s: File name too long\n", name);
1323662Smckusic 		return;
1333662Smckusic 	}
1343662Smckusic 	maxnamlen = cnt;
1353662Smckusic 	filep->funit &= ~TEMP;
1363662Smckusic 	/*
1371656Smckusick 	 * put the new name into the structure
1381656Smckusick 	 */
1391656Smckusick 	for (cnt = 0; cnt < maxnamlen; cnt++)
1401656Smckusick 		filep->fname[cnt] = name[cnt];
1411656Smckusick 	filep->fname[cnt] = '\0';
1421656Smckusick 	filep->pfname = &filep->fname[0];
1431656Smckusick 	return(filep);
1441656Smckusick }
145