#include <mLib/alloc.h>
#include <mLib/dstr.h>
#include <mLib/macros.h>
+#include <mLib/pool.h>
#include "checkpath.h"
};
struct state {
+ pool *p; /* Allocation pool */
struct elt *sp; /* Stack pointer for list */
dstr path; /* Current path string */
};
{
char cwd[PATH_MAX];
struct elt *e, *ee;
- struct state state;
+ struct state *state;
+ pool *pp;
struct stat st;
unsigned bad = 0;
dstr buf = DSTR_INIT;
/* --- Initialize the state --- */
- state.sp = (/*unconst*/ struct elt *)&rootnode;
- dstr_create(&state.path);
+ pp = pool_create(arena_global);
+ state = pool_alloc(pp, sizeof(*state));
+ state->p = pp;
+ state->sp = (/*unconst*/ struct elt *)&rootnode;
+ dstr_create(&state->path);
/* --- Try to find the current directory --- */
/* --- Backtrack on `..' elements --- */
else if (strcmp(ee->e_name, "..") == 0) {
- pop(&state);
+ pop(state);
xfree(ee);
ee = e;
continue;
/* --- Everything else gets pushed on the end --- */
- push(&state, ee);
+ push(state, ee);
ee = e;
/* --- Find out what sort of a thing this is --- */
- if (lstat(state.path.buf, &st)) {
- report(cp, CP_ERROR, 0, state.path.buf, "can't stat: %e");
+ if (lstat(state->path.buf, &st)) {
+ report(cp, CP_ERROR, 0, state->path.buf, "can't stat: %e");
bad |= CP_ERROR;
break;
}
dstr_reset(&buf);
dstr_ensure(&buf, st.st_size + 1);
- if ((i = readlink(state.path.buf, buf.buf, buf.sz)) < 0) {
- report(cp, CP_ERROR, 0, state.path.buf, "can't readlink: %e");
+ if ((i = readlink(state->path.buf, buf.buf, buf.sz)) < 0) {
+ report(cp, CP_ERROR, 0, state->path.buf, "can't readlink: %e");
bad |= CP_ERROR;
break;
}
buf.buf[i] = 0;
- report(cp, CP_SYMLINK, 2, state.path.buf, "symlink -> `%s'", buf.buf);
+ report(cp, CP_SYMLINK, 2, state->path.buf, "symlink -> `%s'", buf.buf);
/* --- Handle sticky parents --- *
*
*/
if ((cp->cp_what & CP_WROTHUSR) &&
- (state.sp->e_link->e_flags & EF_STICKY) &&
+ (state->sp->e_link->e_flags & EF_STICKY) &&
st.st_uid != cp->cp_uid && st.st_uid != 0) {
bad |= CP_WROTHUSR;
- report(cp, CP_WROTHUSR, 1, state.path.buf,
+ report(cp, CP_WROTHUSR, 1, state->path.buf,
"symlink modifiable by user %u", st.st_uid);
}
/* --- Sort out what to do from here --- */
if (buf.buf[0] == '/')
- popall(&state);
+ popall(state);
else
- pop(&state);
+ pop(state);
ee = splitpath(buf.buf, ee);
continue;
}
/* --- Run the sanity check on this path element --- */
- bad |= sanity(state.path.buf, &st, cp, ee ? 0 : SF_LAST);
+ bad |= sanity(state->path.buf, &st, cp, ee ? 0 : SF_LAST);
if (S_ISDIR(st.st_mode)) {
if (st.st_mode & S_ISVTX)
- state.sp->e_flags |= EF_STICKY;
- report(cp, CP_REPORT, 4, state.path.buf, "directory");
+ state->sp->e_flags |= EF_STICKY;
+ report(cp, CP_REPORT, 4, state->path.buf, "directory");
continue;
}
}
}
- popall(&state);
- dstr_destroy(&state.path);
+ popall(state);
+ dstr_destroy(&state->path);
dstr_destroy(&buf);
+ pool_destroy(state->p);
return (bad);
}