+int isadir(const char* f)
+{
+ struct stat s;
+
+ if(stat(f, &s) < 0)
+ {
+ fprintf(stderr, _("Couldn't stat `%s': %m\n"),
+ f);
+ return -1;
+ }
+
+ return S_ISDIR(s.st_mode);
+}
+
+int is_safe_path(const char *file)
+{
+ char *p;
+ struct stat s;
+
+ p = strrchr(file, '/');
+ assert(p); /* p has to contain a / */
+ *p = '\0';
+ if(stat(file, &s) < 0)
+ {
+ fprintf(stderr, _("Couldn't stat `%s': %m\n"),
+ file);
+ return 0;
+ }
+ if(s.st_uid != geteuid())
+ {
+ fprintf(stderr, _("`%s' is owned by UID %d instead of %d.\n"),
+ file, s.st_uid, geteuid());
+ return 0;
+ }
+ if(S_ISLNK(s.st_mode))
+ {
+ fprintf(stderr, _("Warning: `%s' is a symlink\n"),
+ file);
+ /* fixme: read the symlink and start again */
+ }
+
+ *p = '/';
+ if(stat(file, &s) < 0 && errno != ENOENT)
+ {
+ fprintf(stderr, _("Couldn't stat `%s': %m\n"),
+ file);
+ return 0;
+ }
+ if(errno == ENOENT)
+ return 1;
+ if(s.st_uid != geteuid())
+ {
+ fprintf(stderr, _("`%s' is owned by UID %d instead of %d.\n"),
+ file, s.st_uid, geteuid());
+ return 0;
+ }
+ if(S_ISLNK(s.st_mode))
+ {
+ fprintf(stderr, _("Warning: `%s' is a symlink\n"),
+ file);
+ /* fixme: read the symlink and start again */
+ }
+ if(s.st_mode & 0007)
+ {
+ /* Accessible by others */
+ fprintf(stderr, _("`%s' has unsecure permissions.\n"),
+ file);
+ return 0;
+ }
+
+ return 1;
+}