If 'PUBDIR' was given (either by being specified explicitly, or
implicitly if no 'PROGRAM' argument was given), it is checked for
-existence. If it does not exist, *userplex* should return a 404
-response to the client (but see BUGS below).
+existence. If it does not exist, *userplex* returns a 404 response to
+the client.
If there exists a file named `~/.ashd/error` in the user's home
directory, it will be opened in append mode and connected to the
handler to serve files normally. Of course, the second line can be
replaced by whatever other handler one might wish to use.
-BUGS
-----
-
-Currently, *userplex* does not, in fact, return a 404 response to the
-client if the 'PUBDIR' directory does not exist.
-
AUTHOR
------
Fredrik Tolf <fredrik@dolda2000.com>
}
}
-static void execchild(struct passwd *pwd)
+static void discardreq(int fromfd)
+{
+ struct hthead *req;
+ int fd;
+
+ if((fd = recvreq(fromfd, &req)) >= 0) {
+ freehthead(req);
+ close(fd);
+ }
+}
+
+static void execchild(struct passwd *pwd, struct hthead *forreq, int reqfd)
{
if(!ignore)
execl(".ashd/handler", ".ashd/handler", NULL);
if(dirname != NULL) {
- if(access(dirname, X_OK | R_OK))
+ if(access(dirname, X_OK | R_OK)) {
+ discardreq(0);
+ simpleerror(reqfd, 404, "Not Found", "No such resource could be found.");
return;
+ }
}
execvp(childspec[0], childspec);
+ discardreq(0);
+ flog(LOG_ERR, "could not start request handler for user `%s': %s", pwd->pw_name, strerror(errno));
+ simpleerror(reqfd, 500, "User Error", "Could not start any request handler for that user.");
}
-static int forkchild(char *usrnm)
+static int forkchild(char *usrnm, struct hthead *forreq, int reqfd)
{
struct passwd *pwd;
pid_t pid;
close(fd[0]);
close(fd[1]);
login(pwd);
- execchild(pwd);
+ execchild(pwd, forreq, reqfd);
exit(127);
}
close(fd[0]);
static void serve2(struct user *usr, struct hthead *req, int fd)
{
if(usr->fd < 0)
- usr->fd = forkchild(usr->name);
+ usr->fd = forkchild(usr->name, req, fd);
if(sendreq(usr->fd, req, fd)) {
if((errno == EPIPE) || (errno == ECONNRESET)) {
/* Assume that the child has crashed and restart it. */
close(usr->fd);
- usr->fd = forkchild(usr->name);
+ usr->fd = forkchild(usr->name, req, fd);
if(!sendreq(usr->fd, req, fd))
return;
}
flog(LOG_ERR, "could not pass on request to user `%s': %s", usr->name, strerror(errno));
close(usr->fd);
usr->fd = -1;
- simpleerror(fd, 500, "User Error", "The request handler for that user keeps crashing.");
}
}