+ p = strrchr(file, '/');
+
+ if(p == file) /* It's in the root */
+ p++;
+
+ x = *p;
+ *p = '\0';
+
+ f = file;
+check1:
+ if(lstat(f, &s) < 0)
+ {
+ syslog(LOG_ERR, _("Couldn't stat `%s': %m"),
+ f);
+ return 0;
+ }
+
+ if(s.st_uid != geteuid())
+ {
+ syslog(LOG_ERR, _("`%s' is owned by UID %d instead of %d"),
+ f, s.st_uid, geteuid());
+ return 0;
+ }
+
+ if(S_ISLNK(s.st_mode))
+ {
+ syslog(LOG_WARNING, _("Warning: `%s' is a symlink"),
+ f);
+
+ if(readlink(f, l, MAXBUFSIZE) < 0)
+ {
+ syslog(LOG_ERR, _("Unable to read symbolic link `%s': %m"), f);
+ return 0;
+ }
+
+ f = l;
+ goto check1;
+ }
+
+ *p = x;
+ f = file;
+
+check2:
+ if(lstat(f, &s) < 0 && errno != ENOENT)
+ {
+ syslog(LOG_ERR, _("Couldn't stat `%s': %m"),
+ f);
+ return 0;
+ }
+
+ if(errno == ENOENT)
+ return 1;
+
+ if(s.st_uid != geteuid())
+ {
+ syslog(LOG_ERR, _("`%s' is owned by UID %d instead of %d"),
+ f, s.st_uid, geteuid());
+ return 0;
+ }
+
+ if(S_ISLNK(s.st_mode))
+ {
+ syslog(LOG_WARNING, _("Warning: `%s' is a symlink"),
+ f);
+
+ if(readlink(f, l, MAXBUFSIZE) < 0)
+ {
+ syslog(LOG_ERR, _("Unable to read symbolic link `%s': %m"), f);
+ return 0;
+ }
+
+ f = l;
+ goto check2;
+ }
+
+ if(s.st_mode & 0007)
+ {
+ /* Accessible by others */
+ syslog(LOG_ERR, _("`%s' has unsecure permissions"),
+ f);
+ return 0;
+ }
+
+ return 1;
+}
+
+FILE *ask_and_safe_open(const char* filename, const char* what, const char* mode)