commit 921d563a92567c81a7f8597c140afbe9adaf17b7
parent 43967ebf07c808f9a565cf8ab96b73aa49e47577
Author: hhvn <dev@hhvn.uk>
Date: Sat, 5 Jun 2021 19:56:24 +0100
main.c: get raw .plan files
Diffstat:
M | main.c | | | 78 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------- |
1 file changed, 65 insertions(+), 13 deletions(-)
diff --git a/main.c b/main.c
@@ -16,15 +16,16 @@
#define EXIT_USAGE 2
#define CQUEUE 255
-/* strings for getaddrinfo() */
-#define HOST_DFLT "localhost"
-#define PORT_DFLT "79"
+/* defaults, must be strings to replace args */
+char *host = "localhost",
+ *port = "79",
+ *planfile = ".plan";
char *argv0;
void
usage(void) {
- printf("usage: %s [-h host] [-p port]\n", basename(argv0));
+ printf("usage: %s [-h host] [-p port] [-f planfile]\n", basename(argv0));
exit(EXIT_USAGE);
}
@@ -111,8 +112,60 @@ get_userlist(int fd) {
void
get_plan(int fd, char *user) {
- /* TODO */
- return;
+ struct passwd *udata;
+ char path[1024];
+ char buf[4096];
+ int serrno;
+ FILE *plan;
+
+ errno = 0;
+ if ((udata = getpwnam(user)) == NULL) {
+ serrno = errno;
+ if (serrno == 0) {
+ dprintf(fd, "Error: no such user: %s\n", user);
+ } else {
+ dprintf(fd, "Server-side error: %s\n", strerror(serrno));
+ error("getpwnam(): %s\n", strerror(serrno));
+ }
+ }
+
+ /* drop priviledges to user */
+ if (setuid(udata->pw_uid) == -1)
+ error("setuid(): %s\n", strerror(errno));
+
+ snprintf(path, sizeof(path), "%s/%s", udata->pw_dir, planfile);
+ if (access(path, R_OK) == -1) {
+ serrno = errno;
+ switch (serrno) {
+ case ENOTDIR:
+ case ENOENT:
+ dprintf(fd, "Error: user %s does not have a %s file\n",
+ user, planfile);
+ break;
+ default:
+ dprintf(fd, "Error: cannot access user's %s file: %s\n",
+ planfile, strerror(serrno));
+ error("access(): %s: %s\n", path, strerror(serrno));
+ }
+ return;
+ }
+
+ /* TODO: check if executable
+ * and implement "CGI" */
+
+ if ((plan = fopen(path, "rb")) == NULL) {
+ serrno = errno;
+ dprintf(fd, "Error: cannot read user's %s file: %s\n",
+ planfile, strerror(serrno));
+ error("fopen(): %s\n", strerror(serrno));
+ return;
+ }
+
+ /* copy file to fd */
+ while (fgets(buf, sizeof(buf), plan) != NULL)
+ write(fd, buf, strlen(buf));
+ /* don't use sizeof(buf),
+ * or you get heartbleed for free */
}
void
@@ -131,26 +184,25 @@ int
main(int argc, char *argv[]) {
struct sockaddr *addr;
struct addrinfo hints;
- char *host = NULL,
- *port = NULL;
int sock, handle;
int serrno;
pid_t pid;
ARGBEGIN {
case 'h':
+ free(host);
host = EARGF(usage());
break;
case 'p':
+ free(port);
port = EARGF(usage());
break;
+ case 'f':
+ free(planfile);
+ planfile = EARGF(usage());
+ break;
} ARGEND;
- if (host == NULL)
- host = HOST_DFLT;
- if (port == NULL)
- port = PORT_DFLT;
-
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_flags = AI_PASSIVE;