main.c: Add -m command line option to open a named pipe
This write-only named pipe is meant to inform other processes about files that have been added/removed to/from the user/ directory. The syntax is line-oriented and is described below. For added files: +<space ...><path><LF> For removed files: -<space ...><path><LF> Paths shall always be absolute. Examples: + /home/test/db/user/alice/a picture.jpg - /home/test/db/user/bob/essay.txt As reported above, this feature has been made completely optional so as not to introduce breaking changes. A new command line option, namely -m, is required to enable this feature.
This commit is contained in:
parent
838f61e7ed
commit
e8ac71b27e
345
main.c
345
main.c
|
@ -1,6 +1,7 @@
|
|||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include "auth.h"
|
||||
#include "crealpath.h"
|
||||
#include "cftw.h"
|
||||
#include "hex.h"
|
||||
#include "page.h"
|
||||
|
@ -32,6 +33,14 @@ struct form
|
|||
char *key, *value;
|
||||
};
|
||||
|
||||
struct user_args
|
||||
{
|
||||
struct auth *a;
|
||||
struct dynstr d;
|
||||
int fd;
|
||||
bool fifo;
|
||||
};
|
||||
|
||||
static int redirect(struct http_response *const r)
|
||||
{
|
||||
*r = (const struct http_response)
|
||||
|
@ -51,9 +60,9 @@ static int redirect(struct http_response *const r)
|
|||
static int serve_index(const struct http_payload *const p,
|
||||
struct http_response *const r, void *const user)
|
||||
{
|
||||
struct auth *const a = user;
|
||||
const struct user_args *const ua = user;
|
||||
|
||||
if (auth_cookie(a, &p->cookie))
|
||||
if (auth_cookie(ua->a, &p->cookie))
|
||||
return page_login(r);
|
||||
|
||||
return redirect(r);
|
||||
|
@ -63,8 +72,8 @@ static int serve_style(const struct http_payload *const p,
|
|||
struct http_response *const r, void *const user)
|
||||
{
|
||||
int ret = -1;
|
||||
struct auth *const a = user;
|
||||
const char *const dir = auth_dir(a);
|
||||
const struct user_args *const ua = user;
|
||||
const char *const dir = auth_dir(ua->a);
|
||||
struct dynstr d;
|
||||
|
||||
dynstr_init(&d);
|
||||
|
@ -292,7 +301,7 @@ static int login(const struct http_payload *const pl,
|
|||
int ret = -1;
|
||||
size_t n = 0;
|
||||
struct form *forms = NULL;
|
||||
struct auth *const a = user;
|
||||
const struct user_args *const ua = user;
|
||||
char *cookie = NULL;
|
||||
|
||||
if ((ret = get_forms(pl, &forms, &n)))
|
||||
|
@ -302,7 +311,7 @@ static int login(const struct http_payload *const pl,
|
|||
|
||||
goto end;
|
||||
}
|
||||
else if ((ret = check_credentials(a, forms, n, &cookie)))
|
||||
else if ((ret = check_credentials(ua->a, forms, n, &cookie)))
|
||||
{
|
||||
if (ret < 0)
|
||||
fprintf(stderr, "%s: check_credentials failed\n", __func__);
|
||||
|
@ -339,9 +348,9 @@ end:
|
|||
static int logout(const struct http_payload *const p,
|
||||
struct http_response *const r, void *const user)
|
||||
{
|
||||
struct auth *const a = user;
|
||||
const struct user_args *const ua = user;
|
||||
const struct http_cookie *const c = &p->cookie;
|
||||
const int res = auth_cookie(a, c);
|
||||
const int res = auth_cookie(ua->a, c);
|
||||
|
||||
if (res < 0)
|
||||
{
|
||||
|
@ -424,8 +433,8 @@ static int getpublic(const struct http_payload *const p,
|
|||
struct http_response *const r, void *const user)
|
||||
{
|
||||
int ret = -1;
|
||||
struct auth *const a = user;
|
||||
const char *const adir = auth_dir(a);
|
||||
const struct user_args *const ua = user;
|
||||
const char *const adir = auth_dir(ua->a);
|
||||
struct dynstr d;
|
||||
|
||||
dynstr_init(&d);
|
||||
|
@ -698,7 +707,8 @@ static int search(const struct http_payload *const p,
|
|||
struct http_response *const r, void *const user)
|
||||
{
|
||||
int ret = -1;
|
||||
const struct auth *const a = user;
|
||||
const struct user_args *const args = user;
|
||||
const struct auth *const a = args->a;
|
||||
const char *const username = p->cookie.field, *const root = auth_dir(a);
|
||||
struct page_search s = {0};
|
||||
int (*f)(struct http_response *);
|
||||
|
@ -759,7 +769,8 @@ end:
|
|||
static int share(const struct http_payload *const p,
|
||||
struct http_response *const r, void *const user)
|
||||
{
|
||||
struct auth *const a = user;
|
||||
const struct user_args *const ua = user;
|
||||
const struct auth *const a = ua->a;
|
||||
|
||||
if (auth_cookie(a, &p->cookie))
|
||||
{
|
||||
|
@ -916,7 +927,8 @@ static int check_length(const unsigned long long len,
|
|||
static int getnode(const struct http_payload *const p,
|
||||
struct http_response *const r, void *const user)
|
||||
{
|
||||
struct auth *const a = user;
|
||||
const struct user_args *const ua = user;
|
||||
const struct auth *const a = ua->a;
|
||||
|
||||
if (auth_cookie(a, &p->cookie))
|
||||
{
|
||||
|
@ -998,7 +1010,8 @@ end:
|
|||
static int getnode_head(const struct http_payload *const p,
|
||||
struct http_response *const r, void *const user)
|
||||
{
|
||||
struct auth *const a = user;
|
||||
const struct user_args *const args = user;
|
||||
const struct auth *const a = args->a;
|
||||
|
||||
if (auth_cookie(a, &p->cookie))
|
||||
{
|
||||
|
@ -1131,6 +1144,93 @@ static int rename_or_move(const char *const old, const char *const new)
|
|||
return res;
|
||||
}
|
||||
|
||||
static int fifo_writeall(int *const fd, const char *const path,
|
||||
const void *buf, size_t n)
|
||||
{
|
||||
if (*fd < 0 && (*fd = open(path, O_WRONLY | O_NONBLOCK)) < 0)
|
||||
{
|
||||
if (errno == ENXIO)
|
||||
return 0;
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s: open(2): %s\n", __func__, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int ret = -1;
|
||||
|
||||
while (n)
|
||||
{
|
||||
ssize_t res;
|
||||
|
||||
again:
|
||||
|
||||
if ((res = write(*fd, buf, n)) < 0)
|
||||
{
|
||||
switch (errno)
|
||||
{
|
||||
case EAGAIN:
|
||||
/* Fall through. */
|
||||
case EINTR:
|
||||
goto again;
|
||||
|
||||
case EPIPE:
|
||||
{
|
||||
ret = 0;
|
||||
|
||||
if (close(*fd))
|
||||
{
|
||||
fprintf(stderr, "%s: close(2): %s\n",
|
||||
__func__, strerror(errno));
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
*fd = -1;
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
default:
|
||||
fprintf(stderr, "%s: write(2): %s\n",
|
||||
__func__, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
n -= res;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fifo_notify_add(int *const fd, const char *const path,
|
||||
const char *const body)
|
||||
{
|
||||
static const char header[] = "+ ", lf[] = "\n";
|
||||
|
||||
if (fifo_writeall(fd, path, header, strlen(header)))
|
||||
{
|
||||
fprintf(stderr, "%s: fifo_writeall header failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
else if (fifo_writeall(fd, path, body, strlen(body)))
|
||||
{
|
||||
fprintf(stderr, "%s: fifo_writeall body failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
else if (fifo_writeall(fd, path, lf, strlen(lf)))
|
||||
{
|
||||
fprintf(stderr, "%s: fifo_writeall lf failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_upload_dir(const char *const dir)
|
||||
{
|
||||
struct stat sb;
|
||||
|
@ -1162,10 +1262,12 @@ static int check_upload_dir(const char *const dir)
|
|||
}
|
||||
|
||||
static int upload_file(const struct http_post_file *const f,
|
||||
const char *const user, const char *const root, const char *const dir)
|
||||
const char *const user, const char *const root, const char *const dir,
|
||||
struct user_args *const ua)
|
||||
{
|
||||
int ret = -1;
|
||||
struct dynstr dird, d;
|
||||
char *abspath = NULL;
|
||||
|
||||
dynstr_init(&dird);
|
||||
dynstr_init(&d);
|
||||
|
@ -1197,10 +1299,24 @@ static int upload_file(const struct http_post_file *const f,
|
|||
fprintf(stderr, "%s: rename_or_move failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
else if (ua->fifo)
|
||||
{
|
||||
if (!(abspath = crealpath(d.str)))
|
||||
{
|
||||
fprintf(stderr, "%s: crealpath failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
else if (fifo_notify_add(&ua->fd, ua->d.str, abspath))
|
||||
{
|
||||
fprintf(stderr, "%s: fifo_notify_add failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
free(abspath);
|
||||
dynstr_free(&dird);
|
||||
dynstr_free(&d);
|
||||
return ret;
|
||||
|
@ -1258,8 +1374,9 @@ static const char *get_upload_dir(const struct http_post *const po)
|
|||
}
|
||||
|
||||
static int upload_files(const struct http_payload *const p,
|
||||
struct http_response *const r, const struct auth *const a)
|
||||
struct http_response *const r, struct user_args *const ua)
|
||||
{
|
||||
const struct auth *const a = ua->a;
|
||||
const struct http_post *const po = &p->u.post;
|
||||
const char *const root = auth_dir(a), *const user = p->cookie.field,
|
||||
*const dir = get_upload_dir(po);
|
||||
|
@ -1301,7 +1418,7 @@ static int upload_files(const struct http_payload *const p,
|
|||
|
||||
for (size_t i = 0; i < po->nfiles; i++)
|
||||
{
|
||||
const int ret = upload_file(&po->files[i], user, root, dir);
|
||||
const int ret = upload_file(&po->files[i], user, root, dir, ua);
|
||||
|
||||
if (ret < 0)
|
||||
{
|
||||
|
@ -1318,9 +1435,9 @@ static int upload_files(const struct http_payload *const p,
|
|||
static int upload(const struct http_payload *const p,
|
||||
struct http_response *const r, void *const user)
|
||||
{
|
||||
const struct auth *const a = user;
|
||||
struct user_args *const ua = user;
|
||||
|
||||
if (auth_cookie(a, &p->cookie))
|
||||
if (auth_cookie(ua->a, &p->cookie))
|
||||
{
|
||||
fprintf(stderr, "%s: auth_cookie failed\n", __func__);
|
||||
return page_forbidden(r);
|
||||
|
@ -1335,14 +1452,15 @@ static int upload(const struct http_payload *const p,
|
|||
return 0;
|
||||
}
|
||||
|
||||
return upload_files(p, r, a);
|
||||
return upload_files(p, r, ua);
|
||||
}
|
||||
|
||||
static int createdir(const struct http_payload *const p,
|
||||
struct http_response *const r, void *const user)
|
||||
{
|
||||
int ret = -1;
|
||||
struct auth *const a = user;
|
||||
const struct user_args *const ua = user;
|
||||
const struct auth *const a = ua->a;
|
||||
struct dynstr d, userd;
|
||||
struct form *forms = NULL;
|
||||
size_t n = 0;
|
||||
|
@ -1539,14 +1657,14 @@ static int confirm_rm(const struct http_payload *const p,
|
|||
struct http_response *const r, void *const user)
|
||||
{
|
||||
int ret = -1;
|
||||
struct auth *const a = user;
|
||||
const struct user_args *const ua = user;
|
||||
struct form *forms = NULL;
|
||||
const char **items = NULL;
|
||||
size_t n = 0;
|
||||
int (*f)(struct http_response *);
|
||||
struct page_rm rm = {0};
|
||||
|
||||
if (auth_cookie(a, &p->cookie))
|
||||
if (auth_cookie(ua->a, &p->cookie))
|
||||
{
|
||||
fprintf(stderr, "%s: auth_cookie failed\n", __func__);
|
||||
ret = page_forbidden(r);
|
||||
|
@ -1610,36 +1728,82 @@ static const char *find_rm_dir(const struct form *const forms, const size_t n,
|
|||
return dir;
|
||||
}
|
||||
|
||||
static int rm_dir_contents(const char *const fpath,
|
||||
const struct stat *const sb, bool *const done, void *const user)
|
||||
static int fifo_notify_remove(int *const fd, const char *const path,
|
||||
const char *const body)
|
||||
{
|
||||
if (S_ISDIR(sb->st_mode) && rmdir(fpath))
|
||||
static const char header[] = "- ", lf[] = "\n";
|
||||
|
||||
if (fifo_writeall(fd, path, header, strlen(header)))
|
||||
{
|
||||
fprintf(stderr, "%s: rmdir(2) %s: %s\n",
|
||||
__func__, fpath, strerror(errno));
|
||||
fprintf(stderr, "%s: fifo_writeall header failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
else if (S_ISREG(sb->st_mode) && remove(fpath))
|
||||
else if (fifo_writeall(fd, path, body, strlen(body)))
|
||||
{
|
||||
fprintf(stderr, "%s: remove(3) %s: %s\n",
|
||||
__func__, fpath, strerror(errno));
|
||||
fprintf(stderr, "%s: fifo_writeall body failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
else if (fifo_writeall(fd, path, lf, strlen(lf)))
|
||||
{
|
||||
fprintf(stderr, "%s: fifo_writeall lf failed\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rmdir_r(const char *const path)
|
||||
static int rm_dir_contents(const char *const fpath,
|
||||
const struct stat *const sb, bool *const done, void *const user)
|
||||
{
|
||||
int ret = -1;
|
||||
struct user_args *const ua = user;
|
||||
char *abspath = NULL;
|
||||
|
||||
if (S_ISDIR(sb->st_mode) && rmdir(fpath))
|
||||
{
|
||||
fprintf(stderr, "%s: rmdir(2) %s: %s\n",
|
||||
__func__, fpath, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
else if (S_ISREG(sb->st_mode) && remove(fpath))
|
||||
{
|
||||
fprintf(stderr, "%s: remove(3) %s: %s\n",
|
||||
__func__, fpath, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
else if (ua->fifo)
|
||||
{
|
||||
if (!(abspath = crealpath(fpath)))
|
||||
{
|
||||
fprintf(stderr, "%s: crealpath failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
else if (fifo_notify_remove(&ua->fd, ua->d.str, abspath))
|
||||
{
|
||||
fprintf(stderr, "%s: fifo_notify_remove failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
free(abspath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rmdir_r(struct user_args *const ua, const char *const path)
|
||||
{
|
||||
int ret = -1;
|
||||
DIR *const d = opendir(path);
|
||||
char *abspath = NULL;
|
||||
|
||||
if (!d)
|
||||
{
|
||||
fprintf(stderr, "%s: opendir(3): %s\n", __func__, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
else if (cftw(path, rm_dir_contents, NULL))
|
||||
else if (cftw(path, rm_dir_contents, ua))
|
||||
{
|
||||
fprintf(stderr, "%s: rm_dir_contents failed\n", __func__);
|
||||
goto end;
|
||||
|
@ -1650,6 +1814,19 @@ static int rmdir_r(const char *const path)
|
|||
__func__, path, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
else if (ua->fifo)
|
||||
{
|
||||
if (!(abspath = crealpath(path)))
|
||||
{
|
||||
fprintf(stderr, "%s: crealpath failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
else if (fifo_notify_remove(&ua->fd, ua->d.str, abspath))
|
||||
{
|
||||
fprintf(stderr, "%s: fifo_notify_remove failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
|
@ -1660,10 +1837,12 @@ end:
|
|||
ret = -1;
|
||||
}
|
||||
|
||||
free(abspath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int rm_item(const char *const root, const char *const item)
|
||||
static int rm_item(struct user_args *const ua, const char *const root,
|
||||
const char *const item)
|
||||
{
|
||||
int ret = -1;
|
||||
struct stat sb;
|
||||
|
@ -1688,15 +1867,23 @@ static int rm_item(const char *const root, const char *const item)
|
|||
|
||||
goto end;
|
||||
}
|
||||
else if (S_ISDIR(sb.st_mode) && rmdir_r(d.str))
|
||||
else if (S_ISDIR(sb.st_mode) && rmdir_r(ua, d.str))
|
||||
{
|
||||
fprintf(stderr, "%s: rmdir_r failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
else if (S_ISREG(sb.st_mode) && remove(d.str))
|
||||
else if (S_ISREG(sb.st_mode))
|
||||
{
|
||||
fprintf(stderr, "%s: remove(3): %s\n", __func__, strerror(errno));
|
||||
goto end;
|
||||
if (remove(d.str))
|
||||
{
|
||||
fprintf(stderr, "%s: remove(3): %s\n", __func__, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
else if (ua->fifo && fifo_notify_remove(&ua->fd, ua->d.str, d.str))
|
||||
{
|
||||
fprintf(stderr, "%s: fifo_notify_remove failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
@ -1706,8 +1893,8 @@ end:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int do_rm(const struct form *const forms, const size_t n,
|
||||
const char *const dir)
|
||||
static int do_rm(struct user_args *const ua, const struct form *const forms,
|
||||
const size_t n, const char *const dir)
|
||||
{
|
||||
for (size_t i = 0; i < n; i++)
|
||||
{
|
||||
|
@ -1722,7 +1909,7 @@ static int do_rm(const struct form *const forms, const size_t n,
|
|||
fprintf(stderr, "%s: invalid path %s\n", __func__, path);
|
||||
return 1;
|
||||
}
|
||||
else if (rm_item(dir, f->value))
|
||||
else if (rm_item(ua, dir, f->value))
|
||||
{
|
||||
fprintf(stderr, "%s: rm_item failed\n", __func__);
|
||||
return -1;
|
||||
|
@ -1737,7 +1924,8 @@ static int rm(const struct http_payload *const p,
|
|||
struct http_response *const r, void *const user)
|
||||
{
|
||||
int ret = -1;
|
||||
struct auth *const a = user;
|
||||
struct user_args *const ua = user;
|
||||
const struct auth *const a = ua->a;
|
||||
struct form *forms = NULL;
|
||||
size_t n = 0;
|
||||
const struct http_cookie *const c = &p->cookie;
|
||||
|
@ -1788,7 +1976,7 @@ static int rm(const struct http_payload *const p,
|
|||
fprintf(stderr, "%s: dynstr_append failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
else if ((ret = do_rm(forms, n, userdir.str)))
|
||||
else if ((ret = do_rm(ua, forms, n, userdir.str)))
|
||||
{
|
||||
if (ret < 0)
|
||||
fprintf(stderr, "%s: do_rm failed\n", __func__);
|
||||
|
@ -1825,12 +2013,12 @@ end:
|
|||
|
||||
static void usage(char *const argv[])
|
||||
{
|
||||
fprintf(stderr, "%s [-t tmpdir] [-p port] dir\n", *argv);
|
||||
fprintf(stderr, "%s [-F] [-t tmpdir] [-p port] dir\n", *argv);
|
||||
}
|
||||
|
||||
static int parse_args(const int argc, char *const argv[],
|
||||
const char **const dir, unsigned short *const port,
|
||||
const char **const tmpdir)
|
||||
const char **const tmpdir, bool *const fifo)
|
||||
{
|
||||
const char *const envtmp = getenv("TMPDIR");
|
||||
int opt;
|
||||
|
@ -1839,10 +2027,14 @@ static int parse_args(const int argc, char *const argv[],
|
|||
*port = 0;
|
||||
*tmpdir = envtmp ? envtmp : "/tmp";
|
||||
|
||||
while ((opt = getopt(argc, argv, "t:p:")) != -1)
|
||||
while ((opt = getopt(argc, argv, "Ft:p:")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'F':
|
||||
*fifo = true;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
*tmpdir = optarg;
|
||||
break;
|
||||
|
@ -2068,31 +2260,74 @@ static int add_urls(struct handler *const h, void *const user)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ensure_fifo(const char *const dir, struct user_args *const ua)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (dynstr_append(&ua->d, "%s/slcl.fifo", dir))
|
||||
{
|
||||
fprintf(stderr, "%s: dynstr_append failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
else if (mkfifo(ua->d.str, S_IRUSR | S_IWUSR))
|
||||
{
|
||||
fprintf(stderr, "%s: mkfifo(3): %s\n", __func__, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int user_args_free(struct user_args *const ua)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (ua)
|
||||
{
|
||||
if (ua->d.str && remove(ua->d.str))
|
||||
{
|
||||
fprintf(stderr, "%s: remove(3): %s\n", __func__, strerror(errno));
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
auth_free(ua->a);
|
||||
dynstr_free(&ua->d);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret = EXIT_FAILURE;
|
||||
struct handler *h = NULL;
|
||||
struct auth *a = NULL;
|
||||
const char *dir, *tmpdir;
|
||||
unsigned short port;
|
||||
struct user_args ua = {.fd = -1};
|
||||
|
||||
if (parse_args(argc, argv, &dir, &port, &tmpdir)
|
||||
dynstr_init(&ua.d);
|
||||
|
||||
if (parse_args(argc, argv, &dir, &port, &tmpdir, &ua.fifo)
|
||||
|| init_dirs(dir)
|
||||
|| ensure_style(dir)
|
||||
|| !(a = auth_alloc(dir)))
|
||||
|| !(ua.a = auth_alloc(dir))
|
||||
|| (ua.fifo && ensure_fifo(dir, &ua)))
|
||||
goto end;
|
||||
|
||||
const struct handler_cfg cfg =
|
||||
{
|
||||
.length = check_length,
|
||||
.tmpdir = tmpdir,
|
||||
.user = a
|
||||
.user = ua.a
|
||||
};
|
||||
|
||||
unsigned short outport;
|
||||
|
||||
if (!(h = handler_alloc(&cfg))
|
||||
|| add_urls(h, a)
|
||||
|| add_urls(h, &ua)
|
||||
|| handler_listen(h, port, &outport))
|
||||
goto end;
|
||||
|
||||
|
@ -2107,7 +2342,13 @@ int main(int argc, char *argv[])
|
|||
ret = EXIT_SUCCESS;
|
||||
|
||||
end:
|
||||
auth_free(a);
|
||||
handler_free(h);
|
||||
|
||||
if (user_args_free(&ua))
|
||||
{
|
||||
fprintf(stderr, "%s: user_args_free failed\n", __func__);
|
||||
ret = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user