1 /*
2  *   Copyright (C) 1988-1991 Yale University
3  *
4  *   This work is distributed in the hope that it will be useful; you can
5  *   redistribute it and/or modify it under the terms of the
6  *   GNU General Public License as published by the Free Software Foundation;
7  *   either version 2 of the License,
8  *   or any later version, on the following conditions:
9  *
10  *   (a) YALE MAKES NO, AND EXPRESSLY DISCLAIMS
11  *   ALL, REPRESENTATIONS OR WARRANTIES THAT THE MANUFACTURE, USE, PRACTICE,
12  *   SALE OR
13  *   OTHER DISPOSAL OF THE SOFTWARE DOES NOT OR WILL NOT INFRINGE UPON ANY
14  *   PATENT OR
15  *   OTHER RIGHTS NOT VESTED IN YALE.
16  *
17  *   (b) YALE MAKES NO, AND EXPRESSLY DISCLAIMS ALL, REPRESENTATIONS AND
18  *   WARRANTIES
19  *   WHATSOEVER WITH RESPECT TO THE SOFTWARE, EITHER EXPRESS OR IMPLIED,
20  *   INCLUDING,
21  *   BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
22  *   PARTICULAR
23  *   PURPOSE.
24  *
25  *   (c) LICENSEE SHALL MAKE NO STATEMENTS, REPRESENTATION OR WARRANTIES
26  *   WHATSOEVER TO
27  *   ANY THIRD PARTIES THAT ARE INCONSISTENT WITH THE DISCLAIMERS BY YALE IN
28  *   ARTICLE
29  *   (a) AND (b) above.
30  *
31  *   (d) IN NO EVENT SHALL YALE, OR ITS TRUSTEES, DIRECTORS, OFFICERS,
32  *   EMPLOYEES AND
33  *   AFFILIATES BE LIABLE FOR DAMAGES OF ANY KIND, INCLUDING ECONOMIC DAMAGE OR
34  *   INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF WHETHER YALE SHALL BE
35  *   ADVISED, SHALL HAVE OTHER REASON TO KNOW, OR IN FACT SHALL KNOW OF THE
36  *   POSSIBILITY OF THE FOREGOING.
37  *
38  */
39 
40 /* -----------------------------------------------------------------
41 FILE:	    file.c
42 DESCRIPTION:miscellaneous file utility functions
43 CONTENTS:   FILE *YopenFile(char *,char *,int)
44 	    BOOL YfileExists(char *)
45 	    BOOL YdirectoryExists(pathname)
46 		char *pathname ;
47 DATE:	    Jan 29, 1988
48 REVISIONS:  May 04, 1988 - updated initProgram to include
49 			introTextFunction. Added remove_lblanks,
50 			directoryExists functions.
51 	    Sep 26, 1988 - split utils.c into three pieces for archive.
52 	    Jan 26, 1989 - changed directoryExists from macro to routine.
53 	    Apr 27, 1989 - changed to Y prefix.
54 	    Aug 28, 1989 - changed YfileExists to use stat functions
55 		instead of kludge fopen call.
56 	    Fri Feb 22 23:38:59 EST 1991 - added locking functions.
57 	    Tue Mar 12 16:57:30 CST 1991 - modified lock function
58 		to work on apollo - now a level 2 function.
59 	    Thu Apr 18 00:37:52 EDT 1991 - fixed file descriptor.
60 	    Sun Apr 21 21:21:21 EDT 1991 - added Yfile_slink.
61 	    Sat May 11 22:53:09 EDT 1991 - added a conditional compile
62 		for HPUX.
63 	    Oct 07, 1991 - fix #include sys/dir.h for SYS5 A/UX (RAWeier)
64             Oct 18, 1991 - change INT to BOOL in YopenFile (RAWeier)
65 ----------------------------------------------------------------- */
66 
67 #include <stdio.h>
68 #include <yalecad/base.h>
69 #include <yalecad/file.h>
70 #include <yalecad/message.h>
71 #include <yalecad/program.h>
72 
73 #define SERROR  0
74 
75 /* -----------------------------------------------------------------
76                       File routines                                 */
77 
YopenFile(filename,readwrite,abort)78 FILE *YopenFile(filename,readwrite,abort)
79 char *filename ;
80 char *readwrite ;
81 BOOL  abort ;
82 {
83 
84     FILE *fileptr ;
85 
86     fileptr = fopen( filename, readwrite );
87 
88     if( !(fileptr) && abort ){
89 	sprintf( YmsgG,"could not open file %s\n",filename ) ;
90 	M(ERRMSG,"openFile",YmsgG ) ;
91 	YexitPgm(PGMFAIL) ;
92     }
93     return( fileptr ) ;
94 
95 } /* end openFile */
96 
97 
98 #include <sys/types.h>
99 #include <sys/stat.h>
100 #include <unistd.h>
101 
102 /* check if a file exists */
YfileExists(pathname)103 BOOL YfileExists(pathname)
104 char *pathname ;
105 {
106     struct stat buf;
107 
108     if( pathname ){
109 	if( stat(pathname, &buf) == 0 ){
110 	    return(TRUE) ;
111 	}
112     }
113     return(FALSE) ;
114 }
115 
Yfile_slink(pathname)116 char *Yfile_slink( pathname )
117 char *pathname ;
118 {
119     INT len ;
120     static char buf[BUFSIZ] ;
121 
122     len = readlink( pathname, buf, BUFSIZ ) ;
123     if( len <= SERROR ){
124 	sprintf( YmsgG, "ERROR[Yfile_slink]:%s", pathname ) ;
125 	perror( YmsgG ) ;
126 	Ymessage_error_count() ;
127 	return(NIL(char *)) ;
128     } else {
129 	/* null terminate string */
130 	buf[len] = EOS ;
131 	return( buf ) ;
132     }
133 
134 } /* end Yfile_slink */
135 
136 #if defined(__FreeBSD__) || defined(__DragonFly__)
137 #include <dirent.h>
138 #else
139 #include <sys/dir.h>
140 #endif
141 
142 /* check if a directory exists */
YdirectoryExists(pathname)143 BOOL YdirectoryExists(pathname)
144 char *pathname ;
145 {
146     DIR *dp ;
147 
148     if( pathname ){
149 	if( dp = opendir(pathname) ){
150 	    closedir(dp) ;
151 	    return(TRUE) ;
152 	}
153     }
154     return(FALSE) ;
155 }
156 
157 #ifndef HPUX
158 
159 #include <sys/file.h>
Yfile_create_lock(filename,readNotWrite)160 FILE *Yfile_create_lock( filename, readNotWrite )
161 char *filename ;
162 BOOL readNotWrite ;
163 {
164     INT fd ;             /* file descriptor */
165     INT status ;         /* return status */
166     FILE *fp ;           /* file stream descriptor */
167 
168     if(!(YfileExists(filename))){
169 	/* short cut to avoid having to chmod file */
170 	fp = YopenFile( filename, "w", ABORT ) ;
171 	fclose( fp ) ;
172     }
173 
174     if( readNotWrite ){
175 	fd = creat( filename, O_RDONLY ) ;
176     } else {
177 	fd = creat( filename, O_WRONLY ) ;
178     }
179     if( fd <= 0 ){
180 	perror( "Yfile_create_lock" ) ;
181 	sprintf( YmsgG,"could not open file %s\n",filename ) ;
182 	M(ERRMSG,"Yfile_create_lock",YmsgG ) ;
183 	YexitPgm(PGMFAIL) ;
184     }
185     status = flock( fd, LOCK_EX | LOCK_NB ) ;
186     if( status != 0 ){
187 	sprintf( YmsgG,"could not lock file %s\n",filename ) ;
188 	M(ERRMSG,"Yfile_create_lock",YmsgG ) ;
189 	YexitPgm(PGMFAIL) ;
190     }
191     /* now if we get this far find file descriptor */
192     if( readNotWrite ){
193 	fp = fdopen( fd, "r" ) ;
194     } else {
195 	fp = fdopen( fd, "w" ) ;
196     }
197     if(!(fp)){
198 	perror( "Yfile_create_lock" ) ;
199 	sprintf( YmsgG,"could not get file descriptor %s\n",filename ) ;
200 	M(ERRMSG,"Yfile_create_lock",YmsgG ) ;
201 	YexitPgm(PGMFAIL) ;
202     }
203     return( fp ) ;
204 } /* end Yfile_create_lock */
205 
206 /* see a file is locked */
Yfile_test_lock(filename)207 BOOL Yfile_test_lock( filename )
208 char *filename ;
209 {
210     INT fd ;             /* file descriptor */
211     INT status ;         /* return status */
212 
213     if(!(YfileExists(filename))){
214 	/* file does not exist */
215 	return( FALSE ) ;
216     }
217 
218     fd = open( filename, O_RDONLY, 0 ) ;
219     if( fd <= 0 ){
220 	sprintf( YmsgG,"could not open file %s\n",filename ) ;
221 	M(ERRMSG,"Yfile_test_lock",YmsgG ) ;
222 	YexitPgm(PGMFAIL) ;
223     }
224     status = flock( fd, LOCK_EX | LOCK_NB ) ;
225     if( status != 0 ){
226 	return( TRUE ) ;
227     } else {
228 	return( FALSE ) ;
229     }
230 } /* end Yfile_test_lock */
231 
232 #else /* HPUX */
233 
234 #include <unistd.h>
235 #include <sys/file.h>
Yfile_create_lock(filename,readNotWrite)236 FILE *Yfile_create_lock( filename, readNotWrite )
237 char *filename ;
238 BOOL readNotWrite ;
239 {
240     INT fd ;             /* file descriptor */
241     INT status ;         /* return status */
242     FILE *fp ;           /* file stream descriptor */
243 
244     if(!(YfileExists(filename))){
245 	/* short cut to avoid having to chmod file */
246 	fp = YopenFile( filename, "w", ABORT ) ;
247 	fclose( fp ) ;
248     }
249 
250     if( readNotWrite ){
251 	fd = creat( filename, O_RDONLY ) ;
252     } else {
253 	fd = creat( filename, O_WRONLY ) ;
254     }
255     if( fd <= 0 ){
256 	perror( "Yfile_create_lock" ) ;
257 	sprintf( YmsgG,"could not open file %s\n",filename ) ;
258 	M(ERRMSG,"Yfile_create_lock",YmsgG ) ;
259 	YexitPgm(PGMFAIL) ;
260     }
261     status = lockf( fd, F_LOCK, 0 ) ;
262     if( status != 0 ){
263 	sprintf( YmsgG,"could not lock file %s\n",filename ) ;
264 	M(ERRMSG,"Yfile_create_lock",YmsgG ) ;
265 	YexitPgm(PGMFAIL) ;
266     }
267     /* now if we get this far find file descriptor */
268     if( readNotWrite ){
269 	fp = fdopen( fd, "r" ) ;
270     } else {
271 	fp = fdopen( fd, "w" ) ;
272     }
273     if(!(fp)){
274 	sprintf( YmsgG,"could not get file descriptor %s\n",filename ) ;
275 	M(ERRMSG,"Yfile_create_lock",YmsgG ) ;
276 	YexitPgm(PGMFAIL) ;
277     }
278     return( fp ) ;
279 } /* end Yfile_create_lock */
280 
281 /* see a file is locked */
Yfile_test_lock(filename)282 BOOL Yfile_test_lock( filename )
283 char *filename ;
284 {
285     INT fd ;             /* file descriptor */
286     INT status ;         /* return status */
287 
288     if(!(YfileExists(filename))){
289 	/* file does not exist */
290 	return( FALSE ) ;
291     }
292     fd = open( filename, O_RDONLY, 0 ) ;
293     if( fd <= 0 ){
294 	sprintf( YmsgG,"could not open file %s\n",filename ) ;
295 	M(ERRMSG,"Yfile_test_lock",YmsgG ) ;
296 	YexitPgm(PGMFAIL) ;
297     }
298     status = lockf( fd, F_TEST, 0 ) ;
299     if( status != 0 ){
300 	return( TRUE ) ;
301     } else {
302 	return( FALSE ) ;
303     }
304 } /* end Yfile_test_lock */
305 
306 #endif /* HPUX */
307 
308 /* --------------end file routines ------------------------------- */
309