1 /*!
2 \file  fs.c
3 \brief Various file-system functions.
4 
5 This file contains various functions that deal with interfacing with
6 the filesystem in a portable way.
7 
8 \date Started 4/10/95
9 \author George
10 \version\verbatim $Id: fs.c 10711 2011-08-31 22:23:04Z karypis $ \endverbatim
11 */
12 
13 
14 #include <GKlib.h>
15 
16 
17 
18 /*************************************************************************
19 * This function checks if a file exists
20 **************************************************************************/
gk_fexists(char * fname)21 int gk_fexists(char *fname)
22 {
23   struct stat status;
24 
25   if (stat(fname, &status) == -1)
26     return 0;
27 
28   return S_ISREG(status.st_mode);
29 }
30 
31 
32 /*************************************************************************
33 * This function checks if a directory exists
34 **************************************************************************/
gk_dexists(char * dirname)35 int gk_dexists(char *dirname)
36 {
37   struct stat status;
38 
39   if (stat(dirname, &status) == -1)
40     return 0;
41 
42   return S_ISDIR(status.st_mode);
43 }
44 
45 
46 /*************************************************************************/
47 /*! \brief Returns the size of the file in bytes
48 
49 This function returns the size of a file as a 64 bit integer. If there
50 were any errors in stat'ing the file, -1 is returned.
51 \note That due to the -1 return code, the maximum file size is limited to
52       63 bits (which I guess is okay for now).
53 */
54 /**************************************************************************/
gk_getfsize(char * filename)55 intmax_t gk_getfsize(char *filename)
56 {
57   struct stat status;
58 
59   if (stat(filename, &status) == -1)
60     return -1;
61 
62   return (intmax_t)(status.st_size);
63 }
64 
65 
66 /*************************************************************************/
67 /*! This function gets some basic statistics about the file.
68     \param fname is the name of the file
69     \param r_nlines is the number of lines in the file. If it is NULL,
70            this information is not returned.
71     \param r_ntokens is the number of tokens in the file. If it is NULL,
72            this information is not returned.
73     \param r_max_nlntokens is the maximum number of tokens in any line
74            in the file. If it is NULL this information is not returned.
75     \param r_nbytes is the number of bytes in the file. If it is NULL,
76            this information is not returned.
77 */
78 /*************************************************************************/
gk_getfilestats(char * fname,size_t * r_nlines,size_t * r_ntokens,size_t * r_max_nlntokens,size_t * r_nbytes)79 void gk_getfilestats(char *fname, size_t *r_nlines, size_t *r_ntokens,
80         size_t *r_max_nlntokens, size_t *r_nbytes)
81 {
82   size_t nlines=0, ntokens=0, max_nlntokens=0, nbytes=0, oldntokens=0, nread;
83   int intoken=0;
84   char buffer[2049], *cptr;
85   FILE *fpin;
86 
87   fpin = gk_fopen(fname, "r", "gk_GetFileStats");
88 
89   while (!feof(fpin)) {
90     nread = fread(buffer, sizeof(char), 2048, fpin);
91     nbytes += nread;
92 
93     buffer[nread] = '\0';  /* There is space for this one */
94     for (cptr=buffer; *cptr!='\0'; cptr++) {
95       if (*cptr == '\n') {
96         nlines++;
97         ntokens += intoken;
98         intoken = 0;
99         if (max_nlntokens < ntokens-oldntokens)
100           max_nlntokens = ntokens-oldntokens;
101         oldntokens = ntokens;
102       }
103       else if (*cptr == ' ' || *cptr == '\t') {
104         ntokens += intoken;
105         intoken = 0;
106       }
107       else {
108         intoken = 1;
109       }
110     }
111   }
112   ntokens += intoken;
113   if (max_nlntokens < ntokens-oldntokens)
114     max_nlntokens = ntokens-oldntokens;
115 
116   gk_fclose(fpin);
117 
118   if (r_nlines != NULL)
119     *r_nlines  = nlines;
120   if (r_ntokens != NULL)
121     *r_ntokens = ntokens;
122   if (r_max_nlntokens != NULL)
123     *r_max_nlntokens = max_nlntokens;
124   if (r_nbytes != NULL)
125     *r_nbytes  = nbytes;
126 }
127 
128 
129 /*************************************************************************
130 * This function takes in a potentially full path specification of a file
131 * and just returns a string containing just the basename of the file.
132 * The basename is derived from the actual filename by stripping the last
133 * .ext part.
134 **************************************************************************/
gk_getbasename(char * path)135 char *gk_getbasename(char *path)
136 {
137   char *startptr, *endptr;
138   char *basename;
139 
140   if ((startptr = strrchr(path, '/')) == NULL)
141     startptr = path;
142   else
143     startptr = startptr+1;
144 
145   basename = gk_strdup(startptr);
146 
147   if ((endptr = strrchr(basename, '.')) != NULL)
148     *endptr = '\0';
149 
150   return basename;
151 }
152 
153 /*************************************************************************
154 * This function takes in a potentially full path specification of a file
155 * and just returns a string corresponding to its file extension. The
156 * extension of a file is considered to be the string right after the
157 * last '.' character.
158 **************************************************************************/
gk_getextname(char * path)159 char *gk_getextname(char *path)
160 {
161   char *startptr;
162 
163   if ((startptr = strrchr(path, '.')) == NULL)
164     return gk_strdup(path);
165   else
166     return gk_strdup(startptr+1);
167 }
168 
169 /*************************************************************************
170 * This function takes in a potentially full path specification of a file
171 * and just returns a string containing just the filename.
172 **************************************************************************/
gk_getfilename(char * path)173 char *gk_getfilename(char *path)
174 {
175   char *startptr;
176 
177   if ((startptr = strrchr(path, '/')) == NULL)
178     return gk_strdup(path);
179   else
180     return gk_strdup(startptr+1);
181 }
182 
183 /*************************************************************************
184 * This function takes in a potentially full path specification of a file
185 * and extracts the directory path component if it exists, otherwise it
186 * returns "./" as the path. The memory for it is dynamically allocated.
187 **************************************************************************/
getpathname(char * path)188 char *getpathname(char *path)
189 {
190   char *endptr, *tmp;
191 
192   if ((endptr = strrchr(path, '/')) == NULL) {
193     return gk_strdup(".");
194   }
195   else  {
196     tmp = gk_strdup(path);
197     *(strrchr(tmp, '/')) = '\0';
198     return tmp;
199   }
200 }
201 
202 
203 
204 /*************************************************************************
205 * This function creates a path
206 **************************************************************************/
gk_mkpath(char * pathname)207 int gk_mkpath(char *pathname)
208 {
209   char tmp[2048];
210 
211   sprintf(tmp, "mkdir -p %s", pathname);
212   return system(tmp);
213 }
214 
215 
216 /*************************************************************************
217 * This function deletes a directory tree and all of its contents
218 **************************************************************************/
gk_rmpath(char * pathname)219 int gk_rmpath(char *pathname)
220 {
221   char tmp[2048];
222 
223   sprintf(tmp, "rm -r %s", pathname);
224   return system(tmp);
225 }
226