chiark
/
gitweb
/
~mdw
/
checkpath
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
checkpath.c: Move toplevel mutable state into a `state' structure.
[checkpath]
/
checkpath.c
diff --git
a/checkpath.c
b/checkpath.c
index 8d03113789ca7f21912dd6c4dd17e5e2f98c9d60..e4d83e11d079d1ed4fa94ba7267860e0abc65bfd 100644
(file)
--- a/
checkpath.c
+++ b/
checkpath.c
@@
-63,12
+63,14
@@
struct elt {
char e_name[1]; /* Name of the directory */
};
char e_name[1]; /* Name of the directory */
};
+struct state {
+ struct elt *sp; /* Stack pointer for list */
+ dstr path; /* Current path string */
+};
/*----- Static variables --------------------------------------------------*/
static const struct elt rootnode = { 0, 0, 0 }; /* Root of the list */
/*----- Static variables --------------------------------------------------*/
static const struct elt rootnode = { 0, 0, 0 }; /* Root of the list */
-static struct elt *sp; /* Stack pointer for list */
-static dstr d = DSTR_INIT; /* Current path string */
/*----- Main code ---------------------------------------------------------*/
/*----- Main code ---------------------------------------------------------*/
@@
-124,51
+126,54
@@
static struct elt *splitpath(const char *path, struct elt *tail)
/* --- @pop@ --- *
*
/* --- @pop@ --- *
*
- * Arguments:
---
+ * Arguments:
@struct state *state@ = working state
*
* Returns: ---
*
* Use: Removes the top item from the directory stack.
*/
*
* Returns: ---
*
* Use: Removes the top item from the directory stack.
*/
-static void pop(
void
)
+static void pop(
struct state *state
)
{
{
+ struct elt *sp = state->sp, *e;
+
if (sp->e_link) {
if (sp->e_link) {
-
struct elt *
e = sp->e_link;
-
d
.len = sp->e_offset;
- DPUTZ(&
d
);
- xfree(s
p);
sp = e;
+ e = sp->e_link;
+
state->path
.len = sp->e_offset;
+ DPUTZ(&
state->path
);
+ xfree(s
tate->sp); state->
sp = e;
}
}
/* --- @popall@ --- *
*
}
}
/* --- @popall@ --- *
*
- * Arguments:
---
+ * Arguments:
@struct state *state@ = working state
*
* Returns: ---
*
* Use: Removes all the items from the directory stack.
*/
*
* Returns: ---
*
* Use: Removes all the items from the directory stack.
*/
-static void popall(
void
)
- { while (s
p->e_link) pop(
); }
+static void popall(
struct state *state
)
+ { while (s
tate->sp->e_link) pop(state
); }
/* --- @push@ --- *
*
/* --- @push@ --- *
*
- * Arguments: @struct elt *e@ = pointer to directory element
+ * Arguments: @struct state *state@ = working state
+ * @struct elt *e@ = pointer to directory element
*
* Returns: ---
*
* Use: Pushes a new subdirectory onto the stack.
*/
*
* Returns: ---
*
* Use: Pushes a new subdirectory onto the stack.
*/
-static void push(struct elt *e)
+static void push(struct
state *state, struct
elt *e)
{
{
- e->e_link = sp;
- e->e_offset =
d
.len;
- DPUTC(&
d
, '/');
- DPUTS(&
d
, e->e_name);
- sp = e;
+ e->e_link = s
tate->s
p;
+ e->e_offset =
state->path
.len;
+ DPUTC(&
state->path
, '/');
+ DPUTS(&
state->path
, e->e_name);
+ s
tate->s
p = e;
}
/* --- @report@ --- *
}
/* --- @report@ --- *
@@
-350,15
+355,16
@@
unsigned checkpath(const char *p, const struct checkpath *cp)
{
char cwd[PATH_MAX];
struct elt *e, *ee;
{
char cwd[PATH_MAX];
struct elt *e, *ee;
+ struct state state;
struct stat st;
unsigned bad = 0;
dstr buf = DSTR_INIT;
int i;
struct stat st;
unsigned bad = 0;
dstr buf = DSTR_INIT;
int i;
- /* --- Initialize
stack pointer and path string
--- */
+ /* --- Initialize
the state
--- */
- sp = (/*unconst*/ struct elt *)&rootnode;
- dstr_
destroy(&d
);
+ s
tate.s
p = (/*unconst*/ struct elt *)&rootnode;
+ dstr_
create(&state.path
);
/* --- Try to find the current directory --- */
/* --- Try to find the current directory --- */
@@
-399,7
+405,7
@@
unsigned checkpath(const char *p, const struct checkpath *cp)
/* --- Backtrack on `..' elements --- */
else if (strcmp(ee->e_name, "..") == 0) {
/* --- Backtrack on `..' elements --- */
else if (strcmp(ee->e_name, "..") == 0) {
- pop();
+ pop(
&state
);
xfree(ee);
ee = e;
continue;
xfree(ee);
ee = e;
continue;
@@
-407,13
+413,13
@@
unsigned checkpath(const char *p, const struct checkpath *cp)
/* --- Everything else gets pushed on the end --- */
/* --- Everything else gets pushed on the end --- */
- push(ee);
+ push(
&state,
ee);
ee = e;
/* --- Find out what sort of a thing this is --- */
ee = e;
/* --- Find out what sort of a thing this is --- */
- if (lstat(
d
.buf, &st)) {
- report(cp, CP_ERROR, 0,
d
.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;
}
bad |= CP_ERROR;
break;
}
@@
-426,13
+432,13
@@
unsigned checkpath(const char *p, const struct checkpath *cp)
dstr_reset(&buf);
dstr_ensure(&buf, st.st_size + 1);
dstr_reset(&buf);
dstr_ensure(&buf, st.st_size + 1);
- if ((i = readlink(
d
.buf, buf.buf, buf.sz)) < 0) {
- report(cp, CP_ERROR, 0,
d
.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;
bad |= CP_ERROR;
break;
}
buf.buf[i] = 0;
- report(cp, CP_SYMLINK, 2,
d
.buf, "symlink -> `%s'", buf.buf);
+ report(cp, CP_SYMLINK, 2,
state.path
.buf, "symlink -> `%s'", buf.buf);
/* --- Handle sticky parents --- *
*
/* --- Handle sticky parents --- *
*
@@
-442,31
+448,31
@@
unsigned checkpath(const char *p, const struct checkpath *cp)
*/
if ((cp->cp_what & CP_WROTHUSR) &&
*/
if ((cp->cp_what & CP_WROTHUSR) &&
- (sp->e_link->e_flags & EF_STICKY) &&
+ (s
tate.s
p->e_link->e_flags & EF_STICKY) &&
st.st_uid != cp->cp_uid && st.st_uid != 0) {
bad |= CP_WROTHUSR;
st.st_uid != cp->cp_uid && st.st_uid != 0) {
bad |= CP_WROTHUSR;
- report(cp, CP_WROTHUSR, 1,
d
.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] == '/')
"symlink modifiable by user %u", st.st_uid);
}
/* --- Sort out what to do from here --- */
if (buf.buf[0] == '/')
- popall();
+ popall(
&state
);
else
else
- pop();
+ pop(
&state
);
ee = splitpath(buf.buf, ee);
continue;
}
/* --- Run the sanity check on this path element --- */
ee = splitpath(buf.buf, ee);
continue;
}
/* --- Run the sanity check on this path element --- */
- bad |= sanity(
d
.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)
if (S_ISDIR(st.st_mode)) {
if (st.st_mode & S_ISVTX)
- sp->e_flags |= EF_STICKY;
- report(cp, CP_REPORT, 4,
d
.buf, "directory");
+ s
tate.s
p->e_flags |= EF_STICKY;
+ report(cp, CP_REPORT, 4,
state.path
.buf, "directory");
continue;
}
continue;
}
@@
-487,7
+493,8
@@
unsigned checkpath(const char *p, const struct checkpath *cp)
}
}
}
}
- popall();
+ popall(&state);
+ dstr_destroy(&state.path);
dstr_destroy(&buf);
return (bad);
}
dstr_destroy(&buf);
return (bad);
}