1 /* fileutil.c --- Utility functions used by file.c.
2 * Copyright (C) 2002, 2003, 2004, 2007 Simon Josefsson
4 * This file is part of Shishi.
6 * Shishi is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * Shishi is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26 #include <sys/types.h>
37 #include "xreadlink.h"
39 /* Get specification. */
42 #define ishex(c) ((c >= '0' || c <= '9') || (c >= 'a' || c <= 'f'))
43 #define tohex(c1,c2) (((c1 - '0' > 9 ? c1 - 'a' + 10 : c1 - '0') << 4) | \
44 (c2 - '0' > 9 ? c2 - 'a' + 10 : c2 - '0'))
47 unescape_filename (const char *path
)
49 char *out
= strdup (path
);
55 path
[1] && ishex (path
[1]) && path
[2] && ishex (path
[2]))
57 *p
++ = tohex (path
[1], path
[2]);
69 escape_filename (const char *path
)
71 char *out
= malloc (strlen (path
) * 3 + 1);
76 if ((path
[0] >= 'a' && path
[0] <= 'z') ||
77 (path
[0] >= 'A' && path
[0] <= 'Z') ||
78 (path
[0] >= '0' && path
[0] <= '9') ||
79 path
[0] == '-' || path
[0] == '.')
85 i
= (*path
& 0xF0) >> 4;
86 *p
++ = i
> 10 ? 'a' + i
- 10 : '0' + i
;
88 *p
++ = i
> 10 ? 'a' + i
- 10 : '0' + i
;
98 _shisa_isdir (const char *path
)
103 rc
= stat (path
, &buf
);
104 if (rc
!= 0 || !S_ISDIR (buf
.st_mode
))
111 isdir2 (const char *path1
, const char *path2
)
116 asprintf (&tmp
, "%s/%s", path1
, path2
);
118 rc
= _shisa_isdir (tmp
);
127 _shisa_isdir2 (const char *path1
, const char *realm
)
129 char *saferealm
= escape_filename (realm
);
133 asprintf (&tmp
, "%s/%s", path1
, saferealm
);
136 rc
= _shisa_isdir (tmp
);
144 _shisa_isdir3 (const char *path1
, const char *realm
, const char *principal
)
146 char *saferealm
= escape_filename (realm
);
147 char *safeprincipal
= escape_filename (principal
);
151 asprintf (&tmp
, "%s/%s/%s", path1
, saferealm
, safeprincipal
);
153 free (safeprincipal
);
155 rc
= _shisa_isdir (tmp
);
163 _shisa_isdir4 (const char *path1
, const char *realm
,
164 const char *principal
, const char *path4
)
166 char *saferealm
= escape_filename (realm
);
167 char *safeprincipal
= escape_filename (principal
);
171 asprintf (&tmp
, "%s/%s/%s/%s", path1
, saferealm
, safeprincipal
, path4
);
173 free (safeprincipal
);
175 rc
= _shisa_isdir (tmp
);
183 _shisa_mkdir (const char *file
)
187 rc
= mkdir (file
, S_IRUSR
| S_IWUSR
| S_IXUSR
);
198 _shisa_mkdir2 (const char *path1
, const char *realm
)
200 char *saferealm
= escape_filename (realm
);
204 asprintf (&tmp
, "%s/%s", path1
, saferealm
);
207 rc
= _shisa_mkdir (tmp
);
215 _shisa_mkdir3 (const char *path1
, const char *realm
, const char *principal
)
217 char *saferealm
= escape_filename (realm
);
218 char *safeprincipal
= escape_filename (principal
);
222 asprintf (&tmp
, "%s/%s/%s", path1
, saferealm
, safeprincipal
);
224 free (safeprincipal
);
226 rc
= _shisa_mkdir (tmp
);
234 _shisa_mkdir4 (const char *path1
, const char *realm
,
235 const char *principal
, const char *path4
)
237 char *saferealm
= escape_filename (realm
);
238 char *safeprincipal
= escape_filename (principal
);
242 asprintf (&tmp
, "%s/%s/%s/%s", path1
, saferealm
, safeprincipal
, path4
);
244 free (safeprincipal
);
246 rc
= _shisa_mkdir (tmp
);
254 _shisa_rmdir (const char *file
)
269 _shisa_rmdir2 (const char *path1
, const char *realm
)
271 char *saferealm
= escape_filename (realm
);
275 asprintf (&tmp
, "%s/%s", path1
, saferealm
);
278 rc
= _shisa_rmdir (tmp
);
286 _shisa_rmdir3 (const char *path1
, const char *realm
, const char *principal
)
288 char *saferealm
= escape_filename (realm
);
289 char *safeprincipal
= escape_filename (principal
);
293 asprintf (&tmp
, "%s/%s/%s", path1
, saferealm
, safeprincipal
);
295 free (safeprincipal
);
297 rc
= _shisa_rmdir (tmp
);
305 _shisa_rmdir4 (const char *path1
, const char *realm
,
306 const char *principal
, const char *path4
)
308 char *saferealm
= escape_filename (realm
);
309 char *safeprincipal
= escape_filename (principal
);
313 asprintf (&tmp
, "%s/%s/%s/%s", path1
, saferealm
, safeprincipal
, path4
);
315 free (safeprincipal
);
317 rc
= _shisa_rmdir (tmp
);
325 mtime (const char *file
)
330 rc
= stat (file
, &buf
);
331 if (rc
!= 0 || !S_ISREG (buf
.st_mode
))
338 _shisa_mtime4 (const char *path1
,
339 const char *realm
, const char *principal
, const char *path4
)
341 char *saferealm
= escape_filename (realm
);
342 char *safeprincipal
= escape_filename (principal
);
346 asprintf (&tmp
, "%s/%s/%s/%s", path1
, saferealm
, safeprincipal
, path4
);
348 free (safeprincipal
);
358 isfile (const char *path
)
363 rc
= stat (path
, &buf
);
364 if (rc
!= 0 || !S_ISREG (buf
.st_mode
))
371 _shisa_isfile4 (const char *path1
,
372 const char *realm
, const char *principal
, const char *path4
)
374 char *saferealm
= escape_filename (realm
);
375 char *safeprincipal
= escape_filename (principal
);
379 asprintf (&tmp
, "%s/%s/%s/%s", path1
, saferealm
, safeprincipal
, path4
);
381 free (safeprincipal
);
391 uint32link (const char *file
)
395 linkname
= xreadlink (file
);
396 if (linkname
== NULL
)
399 return atol (linkname
);
403 _shisa_uint32link4 (const char *path1
,
405 const char *principal
, const char *path4
)
407 char *saferealm
= escape_filename (realm
);
408 char *safeprincipal
= escape_filename (principal
);
412 asprintf (&tmp
, "%s/%s/%s/%s", path1
, saferealm
, safeprincipal
, path4
);
414 free (safeprincipal
);
416 rc
= uint32link (tmp
);
424 ls_1 (const char *path
, int onlydir
, char ***files
, size_t * nfiles
,
429 while (errno
= 0, (de
= readdir (dir
)) != NULL
)
431 if (strcmp (de
->d_name
, ".") == 0 || strcmp (de
->d_name
, "..") == 0)
433 if (!onlydir
|| isdir2 (path
, de
->d_name
))
437 *files
= xrealloc (*files
, (*nfiles
+ 1) * sizeof (**files
));
438 (*files
)[(*nfiles
)] = unescape_filename (de
->d_name
);
452 for (i
= 0; i
< *nfiles
; i
++)
465 ls (const char *path
, int onlydir
, char ***files
, size_t * nfiles
)
470 dir
= opendir (path
);
477 if (ls_1 (path
, onlydir
, files
, nfiles
, dir
) != 0)
494 for (i
= 0; i
< *nfiles
; i
++)
507 _shisa_ls (const char *path
, char ***files
, size_t * nfiles
)
509 return ls (path
, 0, files
, nfiles
);
513 _shisa_ls2 (const char *path
, const char *realm
,
514 char ***files
, size_t * nfiles
)
516 char *saferealm
= escape_filename (realm
);
520 asprintf (&tmp
, "%s/%s", path
, saferealm
);
523 rc
= _shisa_ls (tmp
, files
, nfiles
);
531 _shisa_ls3 (const char *path
, const char *realm
,
532 const char *principal
, char ***files
, size_t * nfiles
)
534 char *saferealm
= escape_filename (realm
);
535 char *safeprincipal
= escape_filename (principal
);
539 asprintf (&tmp
, "%s/%s/%s", path
, saferealm
, safeprincipal
);
541 free (safeprincipal
);
543 rc
= _shisa_ls (tmp
, files
, nfiles
);
551 _shisa_ls4 (const char *path
, const char *realm
,
552 const char *principal
, const char *path4
,
553 char ***files
, size_t * nfiles
)
555 char *saferealm
= escape_filename (realm
);
556 char *safeprincipal
= escape_filename (principal
);
560 asprintf (&tmp
, "%s/%s/%s/%s", path
, saferealm
, safeprincipal
, path4
);
562 free (safeprincipal
);
564 rc
= _shisa_ls (tmp
, files
, nfiles
);
572 _shisa_lsdir (const char *path
, char ***files
, size_t * nfiles
)
574 return ls (path
, 1, files
, nfiles
);
578 _shisa_lsdir2 (const char *path
, const char *realm
,
579 char ***files
, size_t * nfiles
)
581 char *saferealm
= escape_filename (realm
);
585 asprintf (&tmp
, "%s/%s", path
, saferealm
);
588 rc
= _shisa_lsdir (tmp
, files
, nfiles
);
596 rm (const char *path
)
611 _shisa_rm4 (const char *path1
, const char *realm
,
612 const char *principal
, const char *path4
)
614 char *saferealm
= escape_filename (realm
);
615 char *safeprincipal
= escape_filename (principal
);
619 asprintf (&tmp
, "%s/%s/%s/%s", path1
, saferealm
, safeprincipal
, path4
);
621 free (safeprincipal
);
631 _shisa_rm5 (const char *path1
, const char *realm
, const char *principal
,
632 const char *path4
, const char *path5
)
634 char *saferealm
= escape_filename (realm
);
635 char *safeprincipal
= escape_filename (principal
);
639 asprintf (&tmp
, "%s/%s/%s/%s/%s", path1
, saferealm
, safeprincipal
,
642 free (safeprincipal
);
652 _shisa_fopen4 (const char *path1
, const char *realm
,
653 const char *principal
, const char *path4
, const char *mode
)
655 char *saferealm
= escape_filename (realm
);
656 char *safeprincipal
= escape_filename (principal
);
660 asprintf (&tmp
, "%s/%s/%s/%s", path1
, saferealm
, safeprincipal
, path4
);
662 free (safeprincipal
);
664 fh
= fopen (tmp
, mode
);