1 /*
2  * Miscellaneous routines to get ARC running on non-MSDOS systems...
3  * $Header: /cvsroot/arc/arc/arcmisc.c,v 1.4 2005/10/09 01:38:22 highlandsun Exp $
4  */
5 
6 #include <stdio.h>
7 #include <ctype.h>
8 #include "arc.h"
9 
10 #include <string.h>
11 #if	BSD
12 #include <strings.h>
13 #endif
14 
15 #if	MSDOS
16 #include <dir.h>
17 #include <stat.h>
18 #endif
19 
20 #if	GEMDOS
21 #include <types.h>
22 #include <osbind.h>
23 #include <stat.h>
24 
25 VOID
exitpause()26 exitpause()
27 {
28 	while (Cconis())
29 		Cnecin();
30 	fprintf(stderr, "Press any key to continue: ");
31 	fflush(stderr);
32 	Cnecin();
33 	fprintf(stderr, "\n");
34 }
35 
36 int
chdir(dirname)37 chdir(dirname)
38 	char           *dirname;
39 {
40 	char           *i;
41 	int             drv;
42 
43 	i = dirname;
44 	if ((i = index(dirname, ':')) != NULL) {
45 		drv = i[-1];
46 		i++;		/* Move past device spec */
47 		if (drv > '\'')
48 			drv -= 'a';
49 		else
50 			drv -= 'A';
51 		if (drv >= 0 && drv < 16)
52 			Dsetdrv(drv);
53 	}
54 	if (*i != '\0')
55 		return (Dsetpath(i));
56 }
57 #endif
58 
59 #if	UNIX
60 #include <sys/types.h>
61 #if	SYSV
62 #include <dirent.h>
63 #define DIRECT dirent
64 #else
65 #include <sys/dir.h>
66 #define DIRECT direct
67 #endif
68 #include <sys/stat.h>
69 	int	rename(), unlink();
70 #include <fcntl.h>
71 #endif
72 
73 #if	NEEDMEMSET
74 char	*
memset(s,c,n)75 memset(s, c, n)		/* This came from SVR2? */
76 	char	*s;
77 	int	c, n;
78 {
79 	register int i;
80 	for(i=0;i<n;i++)
81 		s[i]=c;
82 	return(s);
83 }
84 #else
85 #include <memory.h>
86 #endif
87 
88 #ifndef	__STDC__
89 char		*malloc();
90 #ifndef _AIX
91 int		free();
92 #endif
93 #endif
94 int             match();
95 
96 /* Safe open for temp files */
97 FILE *
tmpopen(path)98 tmpopen(path)
99 	char *path;
100 {
101 	int fd = open(path, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
102 	if (fd < 0 )
103 		return NULL;
104 	return fdopen(fd, OPEN_W);
105 }
106 
107 int
move(oldnam,newnam)108 move(oldnam, newnam)
109 	char           *oldnam, *newnam;
110 {
111 	FILE           *fopen(), *old, *new;
112 #if	!_MTS
113 	struct stat     oldstat;
114 #endif
115 	VOID		filecopy();
116 #if	GEMDOS
117 	if (Frename(0, oldnam, newnam))
118 #else
119 	if (rename(oldnam, newnam))
120 #endif
121 #if	!_MTS
122 	{
123 		if (stat(oldnam, &oldstat))	/* different partition? */
124 			return (-1);
125 		old = fopen(oldnam, OPEN_R);
126 		if (old == NULL)
127 			return (-1);
128 		new = fopen(newnam, OPEN_W);
129 		if (new == NULL)
130 			return (-1);
131 		filecopy(old, new, oldstat.st_size);
132 		return(unlink(oldnam));
133 	}
134 	return 0;
135 #else
136 	return(-1);
137 #endif
138 }
139 
140 static VOID
_makefn(source,dest)141 _makefn(source, dest)
142 	char           *source;
143 	char           *dest;
144 {
145 	int             j;
146 #if	MSDOS
147 	char	       *setmem();
148 #endif
149 
150 	setmem(dest, 17, 0);	/* clear result field */
151 	for (j = 0; *source && *source != '.'; ++source)
152 		if (j < 8)
153 			dest[j++] = *source;
154 	for (j = 9; *source; ++source)
155 		if (j < 13)
156 			dest[j++] = *source;
157 }
158 /*
159  * make a file name using a template
160  */
161 
162 char           *
makefnam(rawfn,template,result)163 makefnam(rawfn, template, result)
164 	char           *rawfn;	/* the original file name */
165 	char           *template;	/* the template data */
166 	char           *result;	/* where to place the result */
167 {
168 	char            et[17], er[17], rawbuf[STRLEN], *i;
169 
170 	*rawbuf = 0;
171 	strcpy(rawbuf, rawfn);
172 #if	_MTS
173 	i = rawbuf;
174 	if (rawbuf[0] == tmpchr[0]) {
175 		i++;
176 		strcpy(rawfn, i);
177 	} else
178 #endif
179 	if ((i = rindex(rawbuf, CUTOFF))) {
180 		i++;
181 		strcpy(rawfn, i);
182 	}
183 #if	DOS
184 	else if ((i = rindex(rawbuf, ':'))) {
185 		i++;
186 		strcpy(rawfn, i);
187 	}
188 #endif
189 	if (i)
190 		*i = 0;
191 	else
192 		*rawbuf = 0;
193 
194 	_makefn(template, et);
195 	_makefn(rawfn, er);
196 	*result = 0;		/* assure no data */
197 	strcat(result, rawbuf);
198 	strcat(result, er[0] ? er : et);
199 	strcat(result, er[9] ? er + 9 : et + 9);
200 	return ((char *) &result[0]);
201 }
202 
203 #if	NEED_ALPHASORT
204 
205 int
alphasort(dirptr1,dirptr2)206 alphasort(dirptr1, dirptr2)
207 	struct DIRECT **dirptr1, **dirptr2;
208 {
209 	return (strcmp((*dirptr1)->d_name, (*dirptr2)->d_name));
210 }
211 
212 #endif
213 
214 VOID
upper(string)215 upper(string)
216 	char           *string;
217 {
218 	char           *p;
219 
220 	for (p = string; *p; p++)
221 		if (islower(*p))
222 			*p = toupper(*p);
223 }
224 /* VARARGS1 */
225 VOID
arcdie(s,arg1,arg2,arg3)226 arcdie(s, arg1, arg2, arg3)
227 	char           *s;
228 {
229 	fprintf(stderr, "ARC: ");
230 	fprintf(stderr, s, arg1, arg2, arg3);
231 	fprintf(stderr, "\n");
232 #if	UNIX
233 	perror("UNIX");
234 #endif
235 #if	GEMDOS
236 	exitpause();
237 #endif
238 	exit(1);
239 }
240 
241 #if	!_MTS
242 
243 char           *
gcdir(dirname)244 gcdir(dirname)
245 	char           *dirname;
246 
247 {
248 	char           *getcwd();
249 #if	GEMDOS
250 	int             drv;
251 	char           *buf;
252 #endif
253 	if (dirname == NULL || strlen(dirname) == 0)
254 		dirname = (char *) malloc(1024);
255 
256 #if	!GEMDOS
257 	getcwd(dirname, 1024);
258 #else
259 	buf = dirname;
260 	*buf++ = (drv = Dgetdrv()) + 'A';
261 	*buf++ = ':';
262 	Dgetpath(buf, 0);
263 #endif
264 	return (dirname);
265 }
266 
267 #if	UNIX
268 char           *pattern;	/* global so that fmatch can use it */
269 #endif
270 
271 char           *
dir(filename)272 dir(filename)		/* get files, one by one */
273 	char           *filename;	/* template, or NULL */
274 {
275 #if	GEMDOS
276 	static int      Nnum = 0;
277 #if	__GNUC__
278 #define	d_fname	dta_name	/* Wish these libraries would agree on names */
279 #define DMABUFFER	_DTA
280 #endif
281 	static DMABUFFER dbuf, *saved;
282 	char           *name;
283 	if (Nnum == 0) {	/* first call */
284 		saved = (DMABUFFER *) Fgetdta();
285 		Fsetdta(&dbuf);
286 		if (Fsfirst(filename, 0) == 0) {
287 			name = malloc(FNLEN);
288 			strcpy(name, dbuf.d_fname);
289 			Nnum++;
290 			return (name);
291 		} else {
292 			Fsetdta(saved);
293 			return (NULL);
294 		}
295 	} else {
296 		if (Fsnext() == 0) {
297 			name = malloc(FNLEN);
298 			strcpy(name, dbuf.d_fname);
299 			return (name);
300 		} else {
301 			Nnum = 0;
302 			Fsetdta(saved);
303 			return (NULL);
304 		}
305 	}
306 }
307 #else
308 	static struct DIRECT **namelist;
309 	static char   **NameList;
310 	static char	namecopy[STRLEN], *dirname;
311 #if	UNIX
312 	int             alphasort();
313 	int             scandir();
314 #endif				/* UNIX */
315 	int             fmatch();
316 	static int      Nnum = 0, ii;
317 
318 
319 	if (Nnum == 0) {	/* first call */
320 		strcpy(namecopy,filename);
321 		if((pattern=rindex(namecopy,CUTOFF))) {
322 			*pattern = 0;
323 			pattern++;
324 			dirname = namecopy;
325 		} else {
326 			pattern = filename;
327 			dirname = ".";
328 		}
329 		Nnum = scandir(dirname, &namelist, fmatch, alphasort);
330 		NameList = (char **) malloc(Nnum * sizeof(char *));
331 		for (ii = 0; ii < Nnum; ii++) {
332 			(NameList)[ii] = malloc(strlen(namelist[ii]->d_name) + 1);
333 			strcpy((NameList)[ii], namelist[ii]->d_name);
334 		}
335 		ii = 0;
336 	}
337 	if (ii >= Nnum) {	/* all out of files */
338 		if (Nnum) {	/* there were some files found */
339 			for (ii = 0; ii < Nnum; ii++)
340 				free(namelist[ii]);
341 			free(namelist);
342 		}
343 		Nnum = 0;
344 		return (NULL);
345 	} else {
346 		return ((NameList)[ii++]);
347 	}
348 }
349 
350 /*
351  * Filename match - here, * matches everything
352  */
353 
354 int
355 fmatch(direntry)
356 	struct DIRECT  *direntry;
357 {
358 	char           *string;
359 
360 	string = direntry->d_name;
361 
362 	if (!strcmp(pattern, "") || !strcmp(pattern, "*.*") || !strcmp(pattern, "*"))
363 		return (1);
364 	return (match(string, pattern));
365 }
366 #endif				/* GEMDOS */
367 #else
368 /* dir code for MTS under Bell Labs C... */
369 
370 char           *
dir(filepattern)371 dir(filepattern)
372 	char           *filepattern;	/* template or NULL */
373 {
374 #if	USECATSCAN
375 	fortran VOID    catscan(), fileinfo();
376 
377 	struct catname {
378 		short           len;
379 		char            name[257];
380 	}               pattern;
381 
382 	struct catval {
383 		int             maxlen;
384 		int             actlen;
385 		char            name[257];
386 	}               catreturn;
387 
388 	char           *i;
389 	int             j, RETCODE;
390 
391 	static int      catptr = 0;
392 	static int      catflag = 0x200;
393 	static int      cattype = 1;
394 	static int      patflag = 0;
395 
396 	catreturn.maxlen = 256;
397 
398 	if (patflag) {
399 		patflag = 0;
400 		catptr = 0;
401 		return (NULL);
402 	}
403 	if (filepattern) {
404 		strcpy(pattern.name, filepattern);
405 		pattern.len = strlen(filepattern);
406 		if (!index(filepattern, '?'))
407 			patflag = 1;
408 	}
409 	if (patflag) {
410 		fileinfo(&pattern, &cattype, "CINAME  ", &catreturn, _retcode RETCODE);
411 		catptr = RETCODE ? 0 : 1;
412 	} else
413 		catscan(&pattern, &catflag, &cattype, &catreturn, &catptr);
414 
415 	if (!catptr)
416 		return (NULL);
417 	else {
418 		char           *k;
419 
420 /*		k = index(catreturn.name, ' ');
421 		if (k)
422 			*k = 0;
423 		else {		This seems unnecessary now	*/
424 			j = catreturn.actlen;
425 			catreturn.name[j] = 0;
426 /*		}		*/
427 		k = catreturn.name;
428 		if (*k == tmpchr[0])
429 			k++;
430 		else if ((k = index(catreturn.name, sepchr[0])))
431 			k++;
432 		else
433 			k = catreturn.name;
434 		j = strlen(k);
435 		i = malloc(++j);
436 		strcpy(i, k);
437 		return (i);
438 	}
439 #else
440 	fortran VOID    gfinfo();
441 	static char     gfname[24];
442 	static char     pattern[20];
443 	static int      gfdummy[2] = {
444 				      0, 0
445 	},              gfflags;
446 	int             i, RETCODE;
447 	char           *j, *k;
448 
449 	if (filepattern) {
450 		strcpy(pattern, filepattern);
451 		strcat(pattern, " ");
452 		for (i = 20; i < 24; i++)
453 			gfname[i] = '\0';
454 		if (index(pattern, '?'))
455 			gfflags = 0x0C;
456 		else
457 			gfflags = 0x09;
458 	} else if (gfflags == 0x09)
459 		return (NULL);
460 
461 	gfinfo(pattern, gfname, &gfflags, gfdummy, gfdummy, gfdummy, _retcode RETCODE);
462 	if (RETCODE)
463 		return (NULL);
464 	else {
465 		k = index(gfname, ' ');
466 		*k = '\0';
467 		k = gfname;
468 		if (gfname[0] == tmpchr[0])
469 			k++;
470 		else if ((k = index(gfname, sepchr[0])))
471 			k++;
472 		else
473 			k = gfname;
474 		i = strlen(k);
475 		j = malloc(++i);
476 		strcpy(j, k);
477 		return (j);
478 	}
479 #endif
480 }
481 
482 int
unlink(path)483 unlink(path)
484 	char           *path;	/* name of file to delete */
485 {
486 	fortran VOID    destroy();
487 	int             RETCODE;
488 
489 	char            name[258];
490 
491 	strcpy(name, path);
492 	strcat(name, " ");
493 	destroy(name, _retcode RETCODE);
494 	if (RETCODE)
495 		return (-1);
496 	else
497 		return (0);
498 }
499 #endif
500