chiark / gitweb /
Makefile.am: Tweak `silent-rules' machinery.
[yaid] / policy.c
index 32a455037e8d2b0dc7894665837f16aabb33fda4..9cb9af9b37971f059e8f07f5e57e7cbeb4ee17fd 100644 (file)
--- a/policy.c
+++ b/policy.c
@@ -441,15 +441,22 @@ fail:
 
 /* Open a policy file by NAME.  The description WHAT and query Q are used for
  * formatting error messages for the log.
+ *
+ * This function is somewhat careful only to read from actual regular files,
+ * though (if the filesystem object identified by NAME is a symlink, say) it
+ * might open a device node or other exotic thing without reading it.  This
+ * is likely harmless, since we're running as an unprivileged user anyway.
  */
 int open_policy_file(struct policy_file *pf, const char *name,
-                    const char *what, const struct query *q)
+                    const char *what, const struct query *q, unsigned f)
 {
   struct stat st;
 
   if ((pf->fp = fopen(name, "r")) == 0) {
-    logmsg(q, LOG_ERR, "failed to open %s `%s': %s",
-          what, name, strerror(errno));
+    if (errno != ENOENT || !(f & OPF_NOENTOK)) {
+      logmsg(q, LOG_ERR, "failed to open %s `%s': %s",
+            what, name, strerror(errno));
+    }
     goto err_0;
   }
 
@@ -490,22 +497,20 @@ int read_policy_file(struct policy_file *pf)
     t = parse_policy(pf->fp, &pf->p);
     switch (t) {
       case T_OK:
+      case T_EOL:
        nextline(pf->fp);
-       return (0);
+       return (t);
       case T_ERROR:
        logmsg(pf->q, LOG_ERR, "%s:%d: parse error in %s",
               pf->name, pf->lno, pf->what);
        pf->err = 1;
-       break;
+       return (t);
       case T_EOF:
        if (ferror(pf->fp)) {
          logmsg(pf->q, LOG_ERR, "failed to read %s `%s': %s",
                 pf->what, pf->name, strerror(errno));
        }
-       return (-1);
-      case T_EOL:
-       nextline(pf->fp);
-       break;
+       return (t);
       default:
        abort();
     }
@@ -528,12 +533,15 @@ int load_policy_file(const char *file, policy_v *pv)
 {
   struct policy_file pf;
   policy_v v = DA_INIT;
+  int t = 0;
 
-  if (open_policy_file(&pf, file, "policy file", 0))
+  if (open_policy_file(&pf, file, "policy file", 0, 0))
     return (-1);
-  while (!read_policy_file(&pf)) {
-    DA_PUSH(&v, pf.p);
-    init_policy(&pf.p);
+  while ((t = read_policy_file(&pf)) < T_EOF) {
+    if (t == T_OK) {
+      DA_PUSH(&v, pf.p);
+      init_policy(&pf.p);
+    }
   }
   close_policy_file(&pf);
   if (!pf.err) {