aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog.txt4
-rw-r--r--pseudo_client.c102
-rw-r--r--pseudo_util.c9
3 files changed, 69 insertions, 46 deletions
diff --git a/ChangeLog.txt b/ChangeLog.txt
index 940e781..508fda6 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1,3 +1,7 @@
+2015-01-15:
+ * (seebs) Rework PSEUDO_PASSWD path allocation for clarity,
+ I hope.
+
2015-01-14:
* (seebs) Merge pabigot's fix for a missing antimagic() in
etc_file code.
diff --git a/pseudo_client.c b/pseudo_client.c
index e4be07e..965be6f 100644
--- a/pseudo_client.c
+++ b/pseudo_client.c
@@ -119,59 +119,71 @@ mkdir_p(char *path) {
(void) mkdir(path, 0755);
}
-static int
+/* Populating an array of unknown size is one of my least favorite
+ * things. The idea here is to ensure that the logic flow is the same
+ * both when counting expected items, and when populating them.
+ */
+static void
build_passwd_paths(void)
{
int np = 0;
+ int pass = 0;
- /* determine how many we need */
- if (pseudo_chroot) {
- ++np;
- }
- if (pseudo_passwd) {
- ++np;
- for (int i = 0; pseudo_passwd[i]; ++i)
- if (pseudo_passwd[i] == ':')
- ++np;
- }
- if (PSEUDO_PASSWD_FALLBACK) {
- ++np;
+ /* should never happen... */
+ if (passwd_paths) {
+ free(passwd_paths);
+ passwd_paths = 0;
+ npasswd_paths = 0;
}
- npasswd_paths = np;
- passwd_paths = malloc((np + 1) * sizeof(*passwd_paths));
- if (!passwd_paths) {
- pseudo_diag("couldn't allocate storage for password paths.\n");
- exit(1);
- }
- np = 0;
-#define SHOW_PATH pseudo_debug(PDBGF_CHROOT | PDBGF_VERBOSE, "passwd_paths[%d]: '%s'\n", (np - 1), (passwd_paths[np - 1]))
- if (pseudo_chroot) {
- passwd_paths[np++] = pseudo_chroot;
- SHOW_PATH;
- }
- if (pseudo_passwd) {
- passwd_paths[np++] = pseudo_passwd;
- SHOW_PATH;
- for (int i = 0; pseudo_passwd[i]; ++i) {
- if (pseudo_passwd[i] == ':') {
- pseudo_passwd[i] = '\0';
- passwd_paths[np++] = pseudo_passwd + i + 1;
- SHOW_PATH;
+#define SHOW_PATH pseudo_debug(PDBGF_CHROOT | PDBGF_VERBOSE, "passwd_paths[%d]: '%s'\n", np, (passwd_paths[np]))
+#define ADD_PATH(p) do { if (passwd_paths) { passwd_paths[np] = (p); SHOW_PATH; } ++np; } while(0)
+#define NUL_BYTE(p) do { if (passwd_paths) { *(p)++ = '\0'; } else { ++(p); } } while(0)
+
+ do {
+ if (pseudo_chroot) {
+ ADD_PATH(pseudo_chroot);
+ }
+ if (pseudo_passwd) {
+ char *s = pseudo_passwd;
+ while (s) {
+ char *t = strchr(s, ':');
+ if (t) {
+ NUL_BYTE(t);
+ }
+ ADD_PATH(s);
+ s = t;
}
}
- }
- if (PSEUDO_PASSWD_FALLBACK) {
- passwd_paths[np++] = PSEUDO_PASSWD_FALLBACK;
- SHOW_PATH;
- }
- passwd_paths[np] = NULL;
- if (np != npasswd_paths) {
- pseudo_diag("uh-oh, expected %d path(s) for passwd files, found %d.\n",
- npasswd_paths, np);
- }
-
- return np;
+ if (PSEUDO_PASSWD_FALLBACK) {
+ ADD_PATH(PSEUDO_PASSWD_FALLBACK);
+ }
+
+ /* allocation and/or return */
+ if (passwd_paths) {
+ if (np != npasswd_paths) {
+ pseudo_diag("internal error: path allocation was inconsistent.\n");
+ } else {
+ /* yes, we allocated one extra for a trailing
+ * null pointer.
+ */
+ passwd_paths[np] = NULL;
+ }
+ return;
+ } else {
+ passwd_paths = malloc((np + 1) * sizeof(*passwd_paths));
+ npasswd_paths = np;
+ if (!passwd_paths) {
+ pseudo_diag("couldn't allocate storage for password paths.\n");
+ exit(1);
+ }
+ np = 0;
+ }
+ } while (++pass < 2);
+ /* in theory the second pass already returned, but. */
+ pseudo_diag("should totally not have gotten here.\n");
+
+ return;
}
void
diff --git a/pseudo_util.c b/pseudo_util.c
index d15373b..7f21164 100644
--- a/pseudo_util.c
+++ b/pseudo_util.c
@@ -1286,8 +1286,15 @@ pseudo_etc_file(const char *file, char *realname, int flags, const char **search
}
for (i = 0; i < dircount; ++i) {
const char *s = search_dirs[i];
+ /* we used to pass in some paths as NULL when unset,
+ * so we skipped those. Now NULL entries don't get
+ * put in, so the only NULL should be the sentinel
+ * value, and this should never get hit.
+ *
+ * "should" is not comforting to me.
+ */
if (!s)
- continue;
+ break;
#if PSEUDO_PORT_DARWIN
/* special magic: empty string implies our emulation
* of the passwd/group files.