1 /*
2  * Copyright 1993 University of Liverpool Computer Science Department
3  *
4  * Permission to use, copy, modify, and distribute this software and its
5  * documentation for any purpose and without fee is hereby granted, provided
6  * that the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of L.U.C.S. not be used in advertising
9  * or publicity pertaining to distribution of the software without specific,
10  * written prior permission. L.U.C.S. makes no representations about the
11  * suitability of this software for any purpose.  It is provided "as is"
12  * without express or implied warranty.
13  *
14  * FILE NAME:	file.c
15  * CREATED:	Tue Oct 26 1993
16  * AUTHOR:	Rik Turnbull
17  * DESCRIPTION:	Miscellaneous file handling routines.
18  *
19  */
20 
21 #include <fcntl.h>
22 #include <sys/stat.h>
23 #include <sys/time.h>
24 #include <stdio.h>
25 #include <stdlib.h> /* for free(), malloc() */
26 #include <string.h>
27 #include <utime.h>
28 #include <time.h>
29 
30 #include "stat.h"		/* We use stat_size()           */
31 #include "fname.h"
32 #include "magic.h"
33 
34 int file_exists(char *);	/* Does file exist?             */
35 int file_copy(char *, char *);	/* UNIX cp command              */
36 char *file_load(char *, int *);	/* Load whole file into memory  */
37 char *file_uncompress(char *);  /* Uncompress or ungzip a file  */
38 char *file_stdin();		/* Load all stdin to memory     */
39 
40 /* file_exists:***************************************************************/
41 /* file_exists: See if we can stat this file.                                */
42 /* file_exists:***************************************************************/
43 
file_exists(char * filename)44 int file_exists(char *filename)
45 {
46     struct stat statbuf;
47 
48     if(stat(filename, &statbuf) < 0)
49         return(0);
50     else
51         return(1);
52 }
53 
54 /* file_copy:*****************************************************************/
55 /* file_copy: Just a straight read -> write from one file to another given   */
56 /* file_copy: the file names.                                                */
57 /* file_copy:*****************************************************************/
58 
file_copy(char * fromname,char * toname)59 int file_copy(char *fromname, char *toname)
60 {
61     char buffer[1024];
62     int fromptr, toptr, readbytes;
63 
64     /* Open source file for reading */
65     if((fromptr = open(fromname, O_RDONLY)) < 0)
66         return(0);
67 
68     /* Open destination file for writing */
69     if((toptr = open(toname, O_WRONLY | O_CREAT, (mode_t) 0660)) < 0) {
70         close(fromptr);
71         return(0);
72     }
73 
74     /* Copy the file across */
75     while((readbytes = read(fromptr, buffer, 1024)) > 0) {
76         if(write(toptr, buffer, readbytes) < 0) {
77             close(fromptr);
78             close(toptr);
79             return(0);
80         }
81     }
82 
83     close(fromptr);
84     close(toptr);
85 
86     /* Was the last read() an error? */
87     if(readbytes == -1)
88          return(0);
89 
90     return(1);
91 }
92 
93 /* file_load:*****************************************************************/
94 /* file_load: Read the entire contents of a file into memory.                */
95 /* file_load:*****************************************************************/
96 
file_load(char * filename,int * retsize)97 char *file_load(char *filename, int *retsize)
98 {
99     int size = stat_size(filename);
100     FILE *fp;
101     char *buffer;
102 
103     if((buffer = (char *) malloc(size+1)) == NULL) {
104         if(retsize) *retsize = 0;
105         return(NULL);
106     }
107 
108     if((fp = fopen(filename, "r")) == NULL) {
109         free(buffer);
110         if(retsize) *retsize = 0;
111         return(NULL);
112     }
113 
114     if(read(fileno(fp), buffer, size) != size) {
115         fclose(fp);
116         free(buffer);
117         if(retsize) *retsize = 0;
118         return(NULL);
119     }
120 
121     if(retsize) *retsize = size;
122 
123     buffer[size] = 0;
124 
125     fclose(fp);
126 
127     return(buffer);
128 }
129 
130 /* file_uncompress:**********************************************************/
131 /* file_uncompress: Uncompress the given file with a simple system call.    */
132 /* file_uncompress:**********************************************************/
133 
file_uncompress(char * filename)134 char *file_uncompress(char *filename)
135 {
136     static char newfile[MAXFNAMELEN];
137     char command[BUFSIZ], *ptr, *suffix = NULL;
138 
139     /* Filename to be returned */
140     strcpy(newfile, filename);
141 
142     /* Uncompress depending on compression method */
143     if(is_gzipped(filename)) {
144         if(!env_inpath("gunzip"))
145             return(NULL);
146         sprintf(command, "gunzip -f %s", filename);
147         if(!system(command))
148             return(NULL);
149         suffix = ".gz";
150     }
151     else if(is_compressed(filename)) {
152         if(!env_inpath("uncompress"))
153             return(NULL);
154         sprintf(command, "uncompress -f %s", filename);
155         if(!system(command))
156             return(NULL);
157         suffix = ".Z";
158     }
159 
160     /* Strip of suffix if it was there */
161     if(suffix != NULL) {
162         if((ptr = strstr(newfile, suffix)) != NULL)
163             *ptr = 0;
164     }
165 
166     /* Return uncomprssed filename */
167     return(newfile);
168 }
169 
170 /* file_stdin:****************************************************************/
171 /* file_stdin: Read ALL stdin to memory.                                     */
172 /* file_stdin:****************************************************************/
173 
file_stdin()174 char *file_stdin()
175 {
176     int readbytes = 0, first = 1, total = 0;
177     char buffer[BUFSIZ+1], *newmem, *reply = NULL;
178 
179     /* Read the info from stdin and stick it in a buffer */
180     while((readbytes = read(0, buffer, BUFSIZ)) > 0) {
181         total += readbytes;
182         buffer[readbytes] = 0;
183         if((newmem = (char *) realloc(reply, total + 1)) == NULL) {
184            if(reply != NULL) free(reply);
185            return(NULL);
186         }
187         reply = newmem;
188         /* First time do a strcpy() the rest do a strcat() */
189         if(first) {
190             strcpy(reply, buffer);
191             first = 0;
192         }
193         else
194             strcat(reply, buffer);
195     }
196 
197     return(reply);
198 }
199 
200 /* file_stamp:****************************************************************/
201 /* file_stamp: Change the date stamp on a file.                              */
202 /* file_stamp:****************************************************************/
203 
file_stamp(char * filename,time_t stamp)204 int file_stamp(char *filename, time_t stamp)
205 {
206     int done;
207 #ifdef _USE_UTIMES
208     struct timeval tvp[2];
209 
210     tvp[0].tv_sec  = tvp[1].tv_sec = stamp;
211     tvp[0].tv_usec = tvp[1].tv_usec = 0;
212 
213     done = (utimes(filename, tvp) == 0);
214 #else
215     struct utimbuf utimbuf;
216 
217     utimbuf.actime = stamp;
218     utimbuf.modtime = stamp;
219 
220     done = (utime(filename, &utimbuf) == 0);
221 #endif
222 
223     return(done);
224 }
225