template is a reserved word in C++ s/template/tmpl/.
[platform/upstream/glib.git] / gfileutils.c
1 /* gfileutils.c - File utility functions
2  *
3  *  Copyright 2000 Red Hat, Inc.
4  *
5  * GLib is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU Lesser General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * GLib is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with GLib; see the file COPYING.LIB.  If not,
17  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  *   Boston, MA 02111-1307, USA.
19  */
20
21 #include "config.h"
22
23 #include "glib.h"
24
25 #include <sys/stat.h>
26 #ifdef HAVE_UNISTD_H
27 #include <unistd.h>
28 #endif
29 #include <stdio.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35
36 #ifdef G_OS_WIN32
37 #include <io.h>
38 #ifndef F_OK
39 #define F_OK 0
40 #define X_OK 1
41 #define W_OK 2
42 #define R_OK 4
43 #endif /* !F_OK */
44
45 #ifndef S_ISREG
46 #define S_ISREG(mode) ((mode)&_S_IFREG)
47 #endif
48
49 #ifndef S_ISDIR
50 #define S_ISDIR(mode) ((mode)&_S_IFDIR)
51 #endif
52
53 #endif /* G_OS_WIN32 */
54
55 #ifndef S_ISLNK
56 #define S_ISLNK(x) 0
57 #endif
58
59 #ifndef O_BINARY
60 #define O_BINARY 0
61 #endif
62
63 #define _(x) x
64
65 /**
66  * g_file_test:
67  * @filename: a filename to test
68  * @test: bitfield of #GFileTest flags
69  * 
70  * Returns TRUE if any of the tests in the bitfield @test are
71  * TRUE. For example, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)
72  * will return TRUE if the file exists; the check whether it's
73  * a directory doesn't matter since the existence test is TRUE.
74  * With the current set of available tests, there's no point
75  * passing in more than one test at a time.
76  *
77  * Return value: whether a test was TRUE
78  **/
79 gboolean
80 g_file_test (const gchar *filename,
81              GFileTest    test)
82 {
83   if (test & G_FILE_TEST_EXISTS)
84     return (access (filename, F_OK) == 0);
85   else if (test & G_FILE_TEST_IS_EXECUTABLE)
86     return (access (filename, X_OK) == 0);
87   else
88     {
89       struct stat s;
90       
91       if (stat (filename, &s) < 0)
92         return FALSE;
93
94       if ((test & G_FILE_TEST_IS_REGULAR) &&
95           S_ISREG (s.st_mode))
96         return TRUE;
97       else if ((test & G_FILE_TEST_IS_DIR) &&
98                S_ISDIR (s.st_mode))
99         return TRUE;
100       else if ((test & G_FILE_TEST_IS_SYMLINK) &&
101                S_ISLNK (s.st_mode))
102         return TRUE;
103       else
104         return FALSE;
105     }
106 }
107
108 GQuark
109 g_file_error_quark (void)
110 {
111   static GQuark q = 0;
112   if (q == 0)
113     q = g_quark_from_static_string ("g-file-error-quark");
114
115   return q;
116 }
117
118 GFileError
119 g_file_error_from_errno (gint en)
120 {
121   switch (en)
122     {
123 #ifdef EEXIST
124     case EEXIST:
125       return G_FILE_ERROR_EXIST;
126       break;
127 #endif
128
129 #ifdef EISDIR
130     case EISDIR:
131       return G_FILE_ERROR_ISDIR;
132       break;
133 #endif
134
135 #ifdef EACCES
136     case EACCES:
137       return G_FILE_ERROR_ACCES;
138       break;
139 #endif
140
141 #ifdef ENAMETOOLONG
142     case ENAMETOOLONG:
143       return G_FILE_ERROR_NAMETOOLONG;
144       break;
145 #endif
146
147 #ifdef ENOENT
148     case ENOENT:
149       return G_FILE_ERROR_NOENT;
150       break;
151 #endif
152
153 #ifdef ENOTDIR
154     case ENOTDIR:
155       return G_FILE_ERROR_NOTDIR;
156       break;
157 #endif
158
159 #ifdef ENXIO
160     case ENXIO:
161       return G_FILE_ERROR_NXIO;
162       break;
163 #endif
164
165 #ifdef ENODEV
166     case ENODEV:
167       return G_FILE_ERROR_NODEV;
168       break;
169 #endif
170
171 #ifdef EROFS
172     case EROFS:
173       return G_FILE_ERROR_ROFS;
174       break;
175 #endif
176
177 #ifdef ETXTBSY
178     case ETXTBSY:
179       return G_FILE_ERROR_TXTBSY;
180       break;
181 #endif
182
183 #ifdef EFAULT
184     case EFAULT:
185       return G_FILE_ERROR_FAULT;
186       break;
187 #endif
188
189 #ifdef ELOOP
190     case ELOOP:
191       return G_FILE_ERROR_LOOP;
192       break;
193 #endif
194
195 #ifdef ENOSPC
196     case ENOSPC:
197       return G_FILE_ERROR_NOSPC;
198       break;
199 #endif
200
201 #ifdef ENOMEM
202     case ENOMEM:
203       return G_FILE_ERROR_NOMEM;
204       break;
205 #endif
206
207 #ifdef EMFILE
208     case EMFILE:
209       return G_FILE_ERROR_MFILE;
210       break;
211 #endif
212
213 #ifdef ENFILE
214     case ENFILE:
215       return G_FILE_ERROR_NFILE;
216       break;
217 #endif
218
219 #ifdef EBADF
220     case EBADF:
221       return G_FILE_ERROR_BADF;
222       break;
223 #endif
224
225 #ifdef EINVAL
226     case EINVAL:
227       return G_FILE_ERROR_INVAL;
228       break;
229 #endif
230
231 #ifdef EPIPE
232     case EPIPE:
233       return G_FILE_ERROR_PIPE;
234       break;
235 #endif
236
237 #ifdef EAGAIN
238     case EAGAIN:
239       return G_FILE_ERROR_AGAIN;
240       break;
241 #endif
242
243 #ifdef EINTR
244     case EINTR:
245       return G_FILE_ERROR_INTR;
246       break;
247 #endif
248
249 #ifdef EIO
250     case EIO:
251       return G_FILE_ERROR_IO;
252       break;
253 #endif
254
255 #ifdef EPERM
256     case EPERM:
257       return G_FILE_ERROR_PERM;
258       break;
259 #endif
260       
261     default:
262       return G_FILE_ERROR_FAILED;
263       break;
264     }
265 }
266
267 static gboolean
268 get_contents_stdio (const gchar *filename,
269                     FILE        *f,
270                     gchar      **contents,
271                     guint       *length,
272                     GError     **error)
273 {
274   gchar buf[2048];
275   size_t bytes;
276   GString *str;
277
278   g_assert (f != NULL);
279   
280   str = g_string_new ("");
281   
282   while (!feof (f))
283     {
284       bytes = fread (buf, 1, 2048, f);
285       
286       if (ferror (f))
287         {
288           g_set_error (error,
289                        G_FILE_ERROR,
290                        g_file_error_from_errno (errno),
291                        _("Error reading file '%s': %s"),
292                        filename, strerror (errno));
293
294           g_string_free (str, TRUE);
295           
296           return FALSE;
297         }
298
299       g_string_append_len (str, buf, bytes);
300     }
301
302   fclose (f);
303
304   if (length)
305     *length = str->len;
306   
307   *contents = g_string_free (str, FALSE);
308
309   return TRUE;  
310 }
311
312 #ifndef G_OS_WIN32
313
314 static gboolean
315 get_contents_regfile (const gchar *filename,
316                       struct stat *stat_buf,
317                       gint         fd,
318                       gchar      **contents,
319                       guint       *length,
320                       GError     **error)
321 {
322   gchar *buf;
323   size_t bytes_read;
324   size_t size;
325       
326   size = stat_buf->st_size;
327
328   buf = g_new (gchar, size + 1);
329       
330   bytes_read = 0;
331   while (bytes_read < size)
332     {
333       gint rc;
334           
335       rc = read (fd, buf + bytes_read, size - bytes_read);
336
337       if (rc < 0)
338         {
339           if (errno != EINTR) 
340             {
341               close (fd);
342
343               g_free (buf);
344                   
345               g_set_error (error,
346                            G_FILE_ERROR,
347                            g_file_error_from_errno (errno),
348                            _("Failed to read from file '%s': %s"),
349                            filename, strerror (errno));
350
351               return FALSE;
352             }
353         }
354       else if (rc == 0)
355         break;
356       else
357         bytes_read += rc;
358     }
359       
360   buf[bytes_read] = '\0';
361
362   if (length)
363     *length = bytes_read;
364   
365   *contents = buf;
366
367   return TRUE;
368 }
369
370 static gboolean
371 get_contents_posix (const gchar *filename,
372                     gchar      **contents,
373                     guint       *length,
374                     GError     **error)
375 {
376   struct stat stat_buf;
377   gint fd;
378   
379   fd = open (filename, O_RDONLY);
380
381   if (fd < 0)
382     {
383       g_set_error (error,
384                    G_FILE_ERROR,
385                    g_file_error_from_errno (errno),
386                    _("Failed to open file '%s': %s"),
387                    filename, strerror (errno));
388
389       return FALSE;
390     }
391
392   /* I don't think this will ever fail, aside from ENOMEM, but. */
393   if (fstat (fd, &stat_buf) < 0)
394     {
395       close (fd);
396       
397       g_set_error (error,
398                    G_FILE_ERROR,
399                    g_file_error_from_errno (errno),
400                    _("Failed to get attributes of file '%s': fstat() failed: %s"),
401                    filename, strerror (errno));
402
403       return FALSE;
404     }
405
406   if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode))
407     {
408       return get_contents_regfile (filename,
409                                    &stat_buf,
410                                    fd,
411                                    contents,
412                                    length,
413                                    error);
414     }
415   else
416     {
417       FILE *f;
418
419       f = fdopen (fd, "r");
420       
421       if (f == NULL)
422         {
423           g_set_error (error,
424                        G_FILE_ERROR,
425                        g_file_error_from_errno (errno),
426                        _("Failed to open file '%s': fdopen() failed: %s"),
427                        filename, strerror (errno));
428           
429           return FALSE;
430         }
431   
432       return get_contents_stdio (filename, f, contents, length, error);
433     }
434 }
435
436 #else  /* G_OS_WIN32 */
437
438 static gboolean
439 get_contents_win32 (const gchar *filename,
440                     gchar      **contents,
441                     guint       *length,
442                     GError     **error)
443 {
444   FILE *f;
445
446   /* I guess you want binary mode; maybe you want text sometimes? */
447   f = fopen (filename, "rb");
448
449   if (f == NULL)
450     {
451       g_set_error (error,
452                    G_FILE_ERROR,
453                    g_file_error_from_errno (errno),
454                    _("Failed to open file '%s': %s"),
455                    filename, strerror (errno));
456       
457       return FALSE;
458     }
459   
460   return get_contents_stdio (filename, f, contents, length, error);
461 }
462
463 #endif
464
465 /**
466  * g_file_get_contents:
467  * @filename: a file to read contents from
468  * @contents: location to store an allocated string
469  * @length: location to store length in bytes of the contents
470  * @error: return location for a #GError
471  * 
472  * Reads an entire file into allocated memory, with good error
473  * checking. If @error is set, FALSE is returned, and @contents is set
474  * to NULL. If TRUE is returned, @error will not be set, and @contents
475  * will be set to the file contents.  The string stored in @contents
476  * will be nul-terminated, so for text files you can pass NULL for the
477  * @length argument.  The error domain is #G_FILE_ERROR. Possible
478  * error codes are those in the #GFileError enumeration.
479  *
480  * FIXME currently crashes if the file is too big to fit in memory;
481  * should probably use g_try_malloc() when we have that function.
482  * 
483  * Return value: TRUE on success, FALSE if error is set
484  **/
485 gboolean
486 g_file_get_contents (const gchar *filename,
487                      gchar      **contents,
488                      guint       *length,
489                      GError     **error)
490 {  
491   g_return_val_if_fail (filename != NULL, FALSE);
492   g_return_val_if_fail (contents != NULL, FALSE);
493
494   *contents = NULL;
495   if (length)
496     *length = 0;
497
498 #ifdef G_OS_WIN32
499   return get_contents_win32 (filename, contents, length, error);
500 #else
501   return get_contents_posix (filename, contents, length, error);
502 #endif
503 }
504
505 /*
506  * mkstemp() implementation is from the GNU C library.
507  * Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
508  */
509 /**
510  * g_mkstemp:
511  * @tmpl: template filename
512  *
513  * Open a temporary file. See "man mkstemp" on most UNIX-like systems.
514  * This is a portability wrapper, which simply calls mkstemp() on systems
515  * that have it, and implements it in GLib otherwise.
516  *
517  * The parameter is a string that should match the rules for mktemp, i.e.
518  * end in "XXXXXX". The X string will be modified to form the name
519  * of a file that didn't exist.
520  *
521  * Return value: A file handle (as from open()) to the file
522  * opened for reading and writing. The file is opened in binary mode
523  * on platforms where there is a difference. The file handle should be
524  * closed with close(). In case of errors, -1 is returned.
525  *
526  */
527 int
528 g_mkstemp (char *tmpl)
529 {
530 #ifdef HAVE_MKSTEMP
531   return mkstemp (tmpl);
532 #else
533   int len;
534   char *XXXXXX;
535   int count, fd;
536   static const char letters[] =
537     "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
538   static const int NLETTERS = sizeof (letters) - 1;
539   glong value;
540   GTimeVal tv;
541   static int counter = 0;
542
543   len = strlen (tmpl);
544   if (len < 6 || strcmp (&tmpl[len - 6], "XXXXXX"))
545     return -1;
546
547   /* This is where the Xs start.  */
548   XXXXXX = &tmpl[len - 6];
549
550   /* Get some more or less random data.  */
551   g_get_current_time (&tv);
552   value = (tv.tv_usec ^ tv.tv_sec) + counter++;
553
554   for (count = 0; count < 100; value += 7777, ++count)
555     {
556       glong v = value;
557
558       /* Fill in the random bits.  */
559       XXXXXX[0] = letters[v % NLETTERS];
560       v /= NLETTERS;
561       XXXXXX[1] = letters[v % NLETTERS];
562       v /= NLETTERS;
563       XXXXXX[2] = letters[v % NLETTERS];
564       v /= NLETTERS;
565       XXXXXX[3] = letters[v % NLETTERS];
566       v /= NLETTERS;
567       XXXXXX[4] = letters[v % NLETTERS];
568       v /= NLETTERS;
569       XXXXXX[5] = letters[v % NLETTERS];
570
571       fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
572
573       if (fd >= 0)
574         return fd;
575       else if (errno != EEXIST)
576         /* Any other error will apply also to other names we might
577          *  try, and there are 2^32 or so of them, so give up now.
578          */
579         return -1;
580     }
581
582   /* We got out of the loop because we ran out of combinations to try.  */
583   return -1;
584 #endif
585 }
586
587 /**
588  * g_file_open_tmp:
589  * @tmpl: Template for file name, as in g_mkstemp, basename only
590  * @name_used: location to store actual name used
591  * @error: return location for a #GError
592  *
593  * Opens a file for writing in the preferred directory for temporary
594  * files (as returned by g_get_tmp_dir()). 
595  *
596  * @tmpl should be a string ending with six 'X' characters, as the
597  * parameter to g_mkstemp() (or mkstemp()). However, unlike these
598  * functions, the template should only be a basename, no directory
599  * components are allowed. If template is NULL, a default template is
600  * used.
601  *
602  * Note that in contrast to g_mkstemp() (and mkstemp()) @tmpl is not
603  * modified, and might thus be a read-only literal string.
604  *
605  * The actual name used is returned in @name_used if non-NULL. This
606  * string should be freed with g_free when not needed any longer.
607  *
608  * If some error occurs, @error is set, and -1 is returned. Otherwise,
609  * the file descriptor to a file opened for reading and writing with
610  * g_mkstemp() is returned.
611  **/
612 int
613 g_file_open_tmp (const char *tmpl,
614                  char      **name_used,
615                  GError    **error)
616 {
617   int retval;
618   char *tmpdir;
619   char *sep;
620   char *fulltemplate;
621
622   if (tmpl == NULL)
623     tmpl = ".XXXXXX";
624
625   if (strchr (tmpl, G_DIR_SEPARATOR))
626     {
627       g_set_error (error,
628                    G_FILE_ERROR,
629                    G_FILE_ERROR_FAILED,
630                    _("Template '%s' illegal, should not contain a '%s'"),
631                    tmpl, G_DIR_SEPARATOR_S);
632
633       return -1;
634     }
635   
636   if (strlen (tmpl) < 6 ||
637       strcmp (tmpl + strlen (tmpl) - 6, "XXXXXX") != 0)
638     {
639       g_set_error (error,
640                    G_FILE_ERROR,
641                    G_FILE_ERROR_FAILED,
642                    _("Template '%s' doesn end with XXXXXX"),
643                    tmpl);
644       return -1;
645     }
646
647   tmpdir = g_get_tmp_dir ();
648
649   if (tmpdir [strlen (tmpdir) - 1] == G_DIR_SEPARATOR)
650     sep = "";
651   else
652     sep = G_DIR_SEPARATOR_S;
653
654   fulltemplate = g_strconcat (tmpdir, sep, tmpl, NULL);
655
656   retval = g_mkstemp (fulltemplate);
657
658   if (retval == -1)
659     {
660       g_set_error (error,
661                    G_FILE_ERROR,
662                    g_file_error_from_errno (errno),
663                    _("Failed to create file '%s': %s"),
664                    fulltemplate, strerror (errno));
665       g_free (fulltemplate);
666       return -1;
667     }
668
669   if (name_used)
670     *name_used = fulltemplate;
671   else
672     g_free (fulltemplate);
673
674   return retval;
675 }