From c460974814f23e811d8874ac9836d3ce7cae712b Mon Sep 17 00:00:00 2001 From: Ben Gras Date: Fri, 19 Feb 2010 16:31:43 +0000 Subject: [PATCH] remove subdirs that aren't built. ftp is superseded by other dirs, i86 is not used, httpd* is superseded by packages, sed is superseded by simple/sed.c. --- commands/ftp/Makefile | 33 - commands/ftp/build | 3 - commands/ftp/file.c | 922 -------------------------- commands/ftp/file.h | 30 - commands/ftp/ftp.c | 312 --------- commands/ftp/ftp.h | 36 - commands/ftp/local.c | 128 ---- commands/ftp/local.h | 15 - commands/ftp/net.c | 421 ------------ commands/ftp/net.h | 13 - commands/ftp/other.c | 163 ----- commands/ftp/other.h | 17 - commands/httpd/Makefile | 65 -- commands/httpd/README | 242 ------- commands/httpd/SECURITY | 48 -- commands/httpd/build | 3 - commands/httpd/cgiexec.c | 255 ------- commands/httpd/config.c | 813 ----------------------- commands/httpd/config.h | 84 --- commands/httpd/dir2html.c | 187 ------ commands/httpd/dir2html.sh | 42 -- commands/httpd/http.h | 118 ---- commands/httpd/http_status.5 | 73 -- commands/httpd/httpd.8 | 104 --- commands/httpd/httpd.c | 175 ----- commands/httpd/httpd.conf | 159 ----- commands/httpd/httpd.conf.5 | 328 --------- commands/httpd/httpd.mtype | 40 -- commands/httpd/httpd0993.txt | 41 -- commands/httpd/net.c | 240 ------- commands/httpd/net.h | 17 - commands/httpd/pass.c | 213 ------ commands/httpd/pass.h | 18 - commands/httpd/police.c | 407 ------------ commands/httpd/process.c | 81 --- commands/httpd/proxy.c | 292 -------- commands/httpd/reply.c | 189 ------ commands/httpd/request.c | 369 ----------- commands/httpd/utility.c | 265 -------- commands/httpd/utility.h | 19 - commands/httpd0995/Makefile | 65 -- commands/httpd0995/README | 252 ------- commands/httpd0995/SECURITY | 52 -- commands/httpd0995/cgiexec.c | 255 ------- commands/httpd0995/config.c | 841 ------------------------ commands/httpd0995/config.h | 86 --- commands/httpd0995/dir2html.c | 187 ------ commands/httpd0995/dir2html.sh | 42 -- commands/httpd0995/http.h | 118 ---- commands/httpd0995/http_status.5 | 72 -- commands/httpd0995/httpd.8 | 124 ---- commands/httpd0995/httpd.c | 175 ----- commands/httpd0995/httpd.conf | 166 ----- commands/httpd0995/httpd.conf.5 | 334 ---------- commands/httpd0995/httpd.mtype | 40 -- commands/httpd0995/httpd0995.txt | 59 -- commands/httpd0995/net.c | 240 ------- commands/httpd0995/net.h | 17 - commands/httpd0995/pass.c | 213 ------ commands/httpd0995/pass.h | 18 - commands/httpd0995/police.c | 407 ------------ commands/httpd0995/process.c | 90 --- commands/httpd0995/proxy.c | 292 -------- commands/httpd0995/reply.c | 189 ------ commands/httpd0995/request.c | 369 ----------- commands/httpd0995/utility.c | 265 -------- commands/httpd0995/utility.h | 19 - commands/i86/Makefile | 20 - commands/i86/cc.c | 1059 ------------------------------ commands/sed/BUGS | 10 - commands/sed/Makefile | 22 - commands/sed/README | 81 --- commands/sed/sed.h | 85 --- commands/sed/sedcomp.c | 956 --------------------------- commands/sed/sedexec.c | 819 ----------------------- 75 files changed, 15019 deletions(-) delete mode 100644 commands/ftp/Makefile delete mode 100755 commands/ftp/build delete mode 100644 commands/ftp/file.c delete mode 100644 commands/ftp/file.h delete mode 100644 commands/ftp/ftp.c delete mode 100644 commands/ftp/ftp.h delete mode 100644 commands/ftp/local.c delete mode 100644 commands/ftp/local.h delete mode 100644 commands/ftp/net.c delete mode 100644 commands/ftp/net.h delete mode 100644 commands/ftp/other.c delete mode 100644 commands/ftp/other.h delete mode 100644 commands/httpd/Makefile delete mode 100644 commands/httpd/README delete mode 100644 commands/httpd/SECURITY delete mode 100755 commands/httpd/build delete mode 100644 commands/httpd/cgiexec.c delete mode 100644 commands/httpd/config.c delete mode 100644 commands/httpd/config.h delete mode 100644 commands/httpd/dir2html.c delete mode 100755 commands/httpd/dir2html.sh delete mode 100644 commands/httpd/http.h delete mode 100644 commands/httpd/http_status.5 delete mode 100644 commands/httpd/httpd.8 delete mode 100644 commands/httpd/httpd.c delete mode 100644 commands/httpd/httpd.conf delete mode 100644 commands/httpd/httpd.conf.5 delete mode 100644 commands/httpd/httpd.mtype delete mode 100644 commands/httpd/httpd0993.txt delete mode 100644 commands/httpd/net.c delete mode 100644 commands/httpd/net.h delete mode 100644 commands/httpd/pass.c delete mode 100644 commands/httpd/pass.h delete mode 100644 commands/httpd/police.c delete mode 100644 commands/httpd/process.c delete mode 100644 commands/httpd/proxy.c delete mode 100644 commands/httpd/reply.c delete mode 100644 commands/httpd/request.c delete mode 100644 commands/httpd/utility.c delete mode 100644 commands/httpd/utility.h delete mode 100644 commands/httpd0995/Makefile delete mode 100644 commands/httpd0995/README delete mode 100644 commands/httpd0995/SECURITY delete mode 100644 commands/httpd0995/cgiexec.c delete mode 100644 commands/httpd0995/config.c delete mode 100644 commands/httpd0995/config.h delete mode 100644 commands/httpd0995/dir2html.c delete mode 100755 commands/httpd0995/dir2html.sh delete mode 100644 commands/httpd0995/http.h delete mode 100644 commands/httpd0995/http_status.5 delete mode 100644 commands/httpd0995/httpd.8 delete mode 100644 commands/httpd0995/httpd.c delete mode 100644 commands/httpd0995/httpd.conf delete mode 100644 commands/httpd0995/httpd.conf.5 delete mode 100644 commands/httpd0995/httpd.mtype delete mode 100644 commands/httpd0995/httpd0995.txt delete mode 100644 commands/httpd0995/net.c delete mode 100644 commands/httpd0995/net.h delete mode 100644 commands/httpd0995/pass.c delete mode 100644 commands/httpd0995/pass.h delete mode 100644 commands/httpd0995/police.c delete mode 100644 commands/httpd0995/process.c delete mode 100644 commands/httpd0995/proxy.c delete mode 100644 commands/httpd0995/reply.c delete mode 100644 commands/httpd0995/request.c delete mode 100644 commands/httpd0995/utility.c delete mode 100644 commands/httpd0995/utility.h delete mode 100644 commands/i86/Makefile delete mode 100644 commands/i86/cc.c delete mode 100644 commands/sed/BUGS delete mode 100644 commands/sed/Makefile delete mode 100644 commands/sed/README delete mode 100644 commands/sed/sed.h delete mode 100644 commands/sed/sedcomp.c delete mode 100644 commands/sed/sedexec.c diff --git a/commands/ftp/Makefile b/commands/ftp/Makefile deleted file mode 100644 index 6069e8983..000000000 --- a/commands/ftp/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -# Makefile for ftp -# -# 01/25/96 Initial Release Michael Temari, -# - -CFLAGS= -O -D_MINIX -D_POSIX_SOURCE -LDFLAGS=-i -BINDIR=/usr/bin -PROG= ftp - -OBJS= ftp.o local.o file.o other.o net.o - -all: $(PROG) - -CC = exec cc - -$(PROG): $(OBJS) - $(CC) $(LDFLAGS) -o $@ $(OBJS) - install -S 8kw $@ - -clean: - rm -f $(PROG) $(OBJS) - -install: $(BINDIR)/$(PROG) - -$(BINDIR)/$(PROG): $(PROG) - install -cs -o bin $? $@ - -ftp.o: ftp.c ftp.h local.h file.h other.h net.h -local.o: local.c ftp.h local.h -file.o: file.c ftp.h file.h net.h -other.o: other.c ftp.h other.h -net.o: net.c ftp.h file.h net.h diff --git a/commands/ftp/build b/commands/ftp/build deleted file mode 100755 index 3ee5f0395..000000000 --- a/commands/ftp/build +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -make clean -make && make install diff --git a/commands/ftp/file.c b/commands/ftp/file.c deleted file mode 100644 index 8fdb3e2b7..000000000 --- a/commands/ftp/file.c +++ /dev/null @@ -1,922 +0,0 @@ -/* file.c - * - * This file is part of ftp. - * - * - * 01/25/96 Initial Release Michael Temari, - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ftp.h" -#include "file.h" -#include "net.h" - -_PROTOTYPE(static char *dir, (char *path, int full)); -_PROTOTYPE(static int asciisend, (int fd, int fdout)); -_PROTOTYPE(static int binarysend, (int fd, int fdout)); -_PROTOTYPE(static int asciirecv, (int fd, int fdin)); -_PROTOTYPE(static int binaryrecv, (int fd, int fdin)); -_PROTOTYPE(static int asciisize, (int fd, off_t *filesize)); -_PROTOTYPE(static off_t asciisetsize, (int fd, off_t filesize)); - -static char buffer[512 << sizeof(char *)]; -static char bufout[512 << sizeof(char *)]; -static char line2[512]; - -static char *dir(path, full) -char *path; -int full; -{ -char cmd[128]; -static char name[32]; - - tmpnam(name); - - if(full) - sprintf(cmd, "ls -l %s > %s", path, name); - else - sprintf(cmd, "ls %s > %s", path, name); - - system(cmd); - - return(name); -} - -static int asciisend(fd, fdout) -int fd; -int fdout; -{ -int s, len; -char c; -char *p; -char *op, *ope; -unsigned long total=0L; - - if(atty) { - printf("Sent "); - fflush(stdout); - } - - op = bufout; - ope = bufout + sizeof(bufout) - 3; - - while((s = read(fd, buffer, sizeof(buffer))) > 0) { - total += (long)s; - p = buffer; - while(s-- > 0) { - c = *p++; - if(c == '\r') { - *op++ = '\r'; - total++; - } - *op++ = c; - if(op >= ope) { - write(fdout, bufout, op - bufout); - op = bufout; - } - } - if(atty) { - printf("%9lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total); - fflush(stdout); - } - } - if(op > bufout) - write(fdout, bufout, op - bufout); - if(atty) { - printf("\n"); - fflush(stdout); - } - - return(s); -} - -static int binarysend(fd, fdout) -int fd; -int fdout; -{ -int s; -unsigned long total=0L; - - if(atty) { - printf("Sent "); - fflush(stdout); - } - - while((s = read(fd, buffer, sizeof(buffer))) > 0) { - write(fdout, buffer, s); - total += (long)s; - if(atty) { - printf("%9lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total); - fflush(stdout); - } - } - if(atty) { - printf("\n"); - fflush(stdout); - } - - return(s); -} - -int sendfile(fd, fdout) -int fd; -int fdout; -{ -int s; - - switch(type) { - case TYPE_A: - s = asciisend(fd, fdout); - break; - default: - s = binarysend(fd, fdout); - } - - if(s < 0) - return(-1); - else - return(0); -} - -static int asciirecv(fd, fdin) -int fd; -int fdin; -{ -int s, len; -int gotcr; -char c; -char *p; -char *op, *ope; -unsigned long total=0L; - - if(isatty && fd > 2) { - printf("Received "); - fflush(stdout); - } - gotcr = 0; - op = bufout; ope = bufout + sizeof(bufout) - 3; - while((s = read(fdin, buffer, sizeof(buffer))) > 0) { - p = buffer; - total += (long)s; - while(s-- > 0) { - c = *p++; - if(gotcr) { - gotcr = 0; - if(c != '\n') - *op++ = '\r'; - } - if(c == '\r') - gotcr = 1; - else - *op++ = c; - if(op >= ope) { - write(fd, bufout, op - bufout); - op = bufout; - } - } - if(atty && fd > 2) { - printf("%11lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total); - fflush(stdout); - } - } - if(gotcr) - *op++ = '\r'; - if(op > bufout) - write(fd, bufout, op - bufout); - if(atty && fd > 2) { - printf("\n"); - fflush(stdout); - } - return(s); -} - -static binaryrecv(fd, fdin) -int fd; -int fdin; -{ -int s; -unsigned long total=0L; - - if(atty && fd > 2) { - printf("Received "); - fflush(stdout); - } - while((s = read(fdin, buffer, sizeof(buffer))) > 0) { - write(fd, buffer, s); - total += (long)s; - if(atty && fd > 2) { - printf("%11lu bytes\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b", total); - fflush(stdout); - } - } - if(atty && fd > 2) { - printf("\n"); - fflush(stdout); - } - return(s); -} - -int recvfile(fd, fdin) -int fd; -int fdin; -{ -int s; - - switch(type) { - case TYPE_A: - s = asciirecv(fd, fdin); - break; - default: - s = binaryrecv(fd, fdin); - } - - if(s < 0) - return(-1); - else - return(0); -} - -int DOascii() -{ -int s; - - if(DOcmdcheck()) - return(0); - - s = DOcommand("TYPE", "A"); - - type = TYPE_A; - - return(s); -} - -int DObinary() -{ -int s; - - if(DOcmdcheck()) - return(0); - - s = DOcommand("TYPE", "I"); - - type = TYPE_I; - - return(s); -} - -int DOpwd() -{ -int s; - - if(DOcmdcheck()) - return(0); - - s = DOcommand("PWD", ""); - - if(s == 500 || s == 502) - s = DOcommand("XPWD", ""); - - return(s); -} - -int DOcd() -{ -char *path; -int s; - - if(DOcmdcheck()) - return(0); - - path = cmdargv[1]; - - if(cmdargc < 2) { - readline("Path: ", line2, sizeof(line2)); - path = line2; - } - - if(!strcmp(path, "..")) - s = DOcommand("CDUP", ""); - else - s = DOcommand("CWD", path); - - if(s == 500 || s == 502) { - if(!strcmp(path, "..")) - s = DOcommand("XCUP", ""); - else - s = DOcommand("XCWD", path); - } - - return(s); -} - -int DOmkdir() -{ -char *path; -int s; - - if(DOcmdcheck()) - return(0); - - path = cmdargv[1]; - - if(cmdargc < 2) { - readline("Directory: ", line2, sizeof(line2)); - path = line2; - } - - s = DOcommand("MKD", path); - - if(s == 500 || s == 502) - s = DOcommand("XMKD", path); - - return(s); -} - -int DOrmdir() -{ -char *path; -int s; - - if(DOcmdcheck()) - return(0); - - path = cmdargv[1]; - - if(cmdargc < 2) { - readline("Directory: ", line2, sizeof(line2)); - path = line2; - } - - s = DOcommand("RMD", path); - - if(s == 500 || s == 502) - s = DOcommand("XRMD", path); - - return(s); -} - -int DOdelete() -{ -char *file; - - if(DOcmdcheck()) - return(0); - - file = cmdargv[1]; - - if(cmdargc < 2) { - readline("File: ", line2, sizeof(line2)); - file = line2; - } - - return(DOcommand("DELE", file)); -} - -int DOmdtm() -{ -char *file; - - if(DOcmdcheck()) - return(0); - - file = cmdargv[1]; - - if(cmdargc < 2) { - readline("File: ", line2, sizeof(line2)); - file = line2; - } - - return(DOcommand("MDTM", file)); -} - -int DOsize() -{ -char *file; - - if(DOcmdcheck()) - return(0); - - file = cmdargv[1]; - - if(cmdargc < 2) { - readline("File: ", line2, sizeof(line2)); - file = line2; - } - - return(DOcommand("SIZE", file)); -} - -int DOstat() -{ -char *file; - - if(cmdargc < 2) - if(!linkopen) { - printf("You must \"OPEN\" a connection first.\n"); - return(0); - } else - return(DOcommand("STAT", "")); - - if(DOcmdcheck()) - return(0); - - file = cmdargv[1]; - - if(cmdargc < 2) { - readline("File: ", line2, sizeof(line2)); - file = line2; - } - - return(DOcommand("STAT", file)); -} - -int DOlist() -{ -char *path; -char *local; -int fd; -int s; - - if(DOcmdcheck()) - return(0); - - path = cmdargv[1]; - - if(cmdargc < 2) - path = ""; - - if(cmdargc < 3) - local = ""; - else - local = cmdargv[2]; - - if(*local == '\0') - fd = 1; - else - fd = open(local, O_WRONLY | O_CREAT | O_TRUNC, 0666); - - if(fd < 0) { - printf("Could not open local file %s. Error %s\n", local, strerror(errno)); - return(0); - } - - s = DOdata("LIST", path, RETR, fd); - - if(fd > 2) - close(fd); - - return(s); -} - -int DOnlst() -{ -char *path; -char *local; -int fd; -int s; - - if(DOcmdcheck()) - return(0); - - path = cmdargv[1]; - - if(cmdargc < 2) - path = ""; - - if(cmdargc < 3) - local = ""; - else - local = cmdargv[2]; - - if(*local == '\0') - fd = 1; - else - fd = open(local, O_WRONLY | O_CREAT | O_TRUNC, 0666); - - if(fd < 0) { - printf("Could not open local file %s. Error %s\n", local, strerror(errno)); - return(0); - } - - s = DOdata("NLST", path, RETR, fd); - - if(fd > 2) - close(fd); - - return(s); -} - -int DOretr() -{ -char *file, *localfile; -int fd; -int s; - - if(DOcmdcheck()) - return(0); - - file = cmdargv[1]; - - if(cmdargc < 2) { - readline("Remote File: ", line2, sizeof(line2)); - file = line2; - } - - if(cmdargc < 3) - localfile = file; - else - localfile = cmdargv[2]; - - fd = open(localfile, O_WRONLY | O_CREAT | O_TRUNC, 0666); - - if(fd < 0) { - printf("Could not open local file %s. Error %s\n", localfile, strerror(errno)); - return(0); - } - - s = DOdata("RETR", file, RETR, fd); - - close(fd); - - return(s); -} - -int DOrretr() -{ -char *file, *localfile; -int fd; -int s; -off_t filesize; -char restart[16]; - - if(DOcmdcheck()) - return(0); - - file = cmdargv[1]; - - if(cmdargc < 2) { - readline("Remote File: ", line2, sizeof(line2)); - file = line2; - } - - if(cmdargc < 3) - localfile = file; - else - localfile = cmdargv[2]; - - fd = open(localfile, O_RDWR); - - if(fd < 0) { - printf("Could not open local file %s. Error %s\n", localfile, strerror(errno)); - return(0); - } - - if(type == TYPE_A) { - if(asciisize(fd, &filesize)) { - printf("Could not determine ascii file size of %s\n", localfile); - close(fd); - return(0); - } - } else - filesize = lseek(fd, 0, SEEK_END); - - sprintf(restart, "%lu", filesize); - - s = DOcommand("REST", restart); - - if(s != 350) { - close(fd); - return(s); - } - - s = DOdata("RETR", file, RETR, fd); - - close(fd); - - return(s); -} - -int DOMretr() -{ -char *files; -int fd, s; -FILE *fp; -char name[32]; - - if(DOcmdcheck()) - return(0); - - files = cmdargv[1]; - - if(cmdargc < 2) { - readline("Files: ", line2, sizeof(line2)); - files = line2; - } - - tmpnam(name); - - fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666); - - if(fd < 0) { - printf("Could not open local file %s. Error %s\n", name, strerror(errno)); - return(0); - } - - s = DOdata("NLST", files, RETR, fd); - - close(fd); - - if(s == 226) { - fp = fopen(name, "r"); - unlink(name); - if(fp == (FILE *)NULL) { - printf("Unable to open file listing.\n"); - return(0); - } - while(fgets(line2, sizeof(line2), fp) != (char *)NULL) { - line2[strlen(line2)-1] = '\0'; - printf("Retrieving file: %s\n", line2); fflush(stdout); - fd = open(line2, O_WRONLY | O_CREAT | O_TRUNC, 0666); - if(fd < 0) - printf("Unable to open local file %s\n", line2); - else { - s = DOdata("RETR", line2, RETR, fd); - close(fd); - if(s < 0) break; - } - } - fclose(fp); - } else - unlink(name); - - return(s); -} - -int DOappe() -{ -char *file, *remotefile; -int fd; -int s; - - if(DOcmdcheck()) - return(0); - - file = cmdargv[1]; - - if(cmdargc < 2) { - readline("Local File: ", line2, sizeof(line2)); - file = line2; - } - - if(cmdargc < 3) - remotefile = file; - else - remotefile = cmdargv[2]; - - fd = open(file, O_RDONLY); - - if(fd < 0) { - printf("Could not open local file %s. Error %s\n", file, strerror(errno)); - return(0); - } - - s = DOdata("APPE", remotefile, STOR, fd); - - close(fd); - - return(s); -} - -int DOstor() -{ -char *file, *remotefile; -int fd; -int s; - - if(DOcmdcheck()) - return(0); - - file = cmdargv[1]; - - if(cmdargc < 2) { - readline("Local File: ", line2, sizeof(line2)); - file = line2; - } - - if(cmdargc < 3) - remotefile = file; - else - remotefile = cmdargv[2]; - - fd = open(file, O_RDONLY); - - if(fd < 0) { - printf("Could not open local file %s. Error %s\n", file, strerror(errno)); - return(0); - } - - s = DOdata("STOR", remotefile, STOR, fd); - - close(fd); - - return(s); -} - -int DOrstor() -{ -char *file, *remotefile; -int fd; -int s; -off_t filesize, rmtsize; -char restart[16]; - - if(DOcmdcheck()) - return(0); - - file = cmdargv[1]; - - if(cmdargc < 2) { - readline("Local File: ", line2, sizeof(line2)); - file = line2; - } - - if(cmdargc < 3) - remotefile = file; - else - remotefile = cmdargv[2]; - - s = DOcommand("SIZE", remotefile); - - if(s != 215) - return(s); - - rmtsize = atol(reply+4); - - fd = open(file, O_RDONLY); - - if(fd < 0) { - printf("Could not open local file %s. Error %s\n", file, strerror(errno)); - return(0); - } - - if(type == TYPE_A) - filesize = asciisetsize(fd, rmtsize); - else - filesize = lseek(fd, rmtsize, SEEK_SET); - - if(filesize != rmtsize) { - printf("Could not set file start of %s\n", file); - close(fd); - return(0); - } - - sprintf(restart, "%lu", rmtsize); - - s = DOcommand("REST", restart); - - if(s != 350) { - close(fd); - return(s); - } - - s = DOdata("STOR", remotefile, STOR, fd); - - close(fd); - - return(s); -} - -int DOstou() -{ -char *file, *remotefile; -int fd; -int s; - - if(DOcmdcheck()) - return(0); - - file = cmdargv[1]; - - if(cmdargc < 2) { - readline("Local File: ", line2, sizeof(line2)); - file = line2; - } - - if(cmdargc < 3) - remotefile = file; - else - remotefile = cmdargv[2]; - - fd = open(file, O_RDONLY); - - if(fd < 0) { - printf("Could not open local file %s. Error %s\n", file, strerror(errno)); - return(0); - } - - s = DOdata("STOU", remotefile, STOR, fd); - - close(fd); - - return(s); -} - -int DOMstor() -{ -char *files; -char *name; -int fd, s; -FILE *fp; - - if(DOcmdcheck()) - return(0); - - files = cmdargv[1]; - - if(cmdargc < 2) { - readline("Files: ", line2, sizeof(line2)); - files = line2; - } - - name = dir(files, 0); - - fp = fopen(name, "r"); - - if(fp == (FILE *)NULL) { - printf("Unable to open listing file.\n"); - return(0); - } - - while(fgets(line2, sizeof(line2), fp) != (char *)NULL) { - line2[strlen(line2)-1] = '\0'; - printf("Sending file: %s\n", line2); fflush(stdout); - fd = open(line2, O_RDONLY); - if(fd < 0) - printf("Unable to open local file %s\n", line2); - else { - s = DOdata("STOR", line2, STOR, fd); - close(fd); - if(s < 0) break; - } - } - fclose(fp); - unlink(name); - - return(s); -} - -static int asciisize(fd, filesize) -int fd; -off_t *filesize; -{ -unsigned long count; -char *p, *pp; -int cnt; - - count = 0; - - while((cnt = read(fd, buffer, sizeof(buffer))) > 0) { - p = buffer; pp = buffer + cnt; - count += cnt; - while(p < pp) - if(*p++ == '\n') - count++; - } - - if(cnt == 0) { - *filesize = count; - return(0); - } - - return(1); -} - -static off_t asciisetsize(fd, filesize) -int fd; -off_t filesize; -{ -off_t sp; -int s; - - sp = 0; - - while(sp < filesize) { - s = read(fd, buffer, 1); - if(s < 0) - return(-1); - if(s == 0) break; - sp++; - if(*buffer == '\n') - sp++; - } - - return(sp); -} diff --git a/commands/ftp/file.h b/commands/ftp/file.h deleted file mode 100644 index 3e79e65a6..000000000 --- a/commands/ftp/file.h +++ /dev/null @@ -1,30 +0,0 @@ -/* file.h - * - * This file is part of ftp. - * - * - * 01/25/96 Initial Release Michael Temari, - */ - -_PROTOTYPE(int recvfile, (int fd, int fdin)); -_PROTOTYPE(int sendfile, (int fd, int fdout)); -_PROTOTYPE(int DOascii, (void)); -_PROTOTYPE(int DObinary, (void)); -_PROTOTYPE(int DOpwd, (void)); -_PROTOTYPE(int DOcd, (void)); -_PROTOTYPE(int DOmkdir, (void)); -_PROTOTYPE(int DOrmdir, (void)); -_PROTOTYPE(int DOdelete, (void)); -_PROTOTYPE(int DOmdtm, (void)); -_PROTOTYPE(int DOsize, (void)); -_PROTOTYPE(int DOstat, (void)); -_PROTOTYPE(int DOlist, (void)); -_PROTOTYPE(int DOnlst, (void)); -_PROTOTYPE(int DOretr, (void)); -_PROTOTYPE(int DOrretr, (void)); -_PROTOTYPE(int DOMretr, (void)); -_PROTOTYPE(int DOappe, (void)); -_PROTOTYPE(int DOstor, (void)); -_PROTOTYPE(int DOrstor, (void)); -_PROTOTYPE(int DOstou, (void)); -_PROTOTYPE(int DOMstor, (void)); diff --git a/commands/ftp/ftp.c b/commands/ftp/ftp.c deleted file mode 100644 index 464e40c99..000000000 --- a/commands/ftp/ftp.c +++ /dev/null @@ -1,312 +0,0 @@ -/* ftp.c by Michael Temari 06/21/92 - * - * ftp An ftp client program for use with TNET. - * - * Usage: ftp [[host] [port]] - * - * Version: 0.10 06/21/92 (pre-release not yet completed) - * 0.20 07/01/92 - * 0.30 01/15/96 (Minix 1.7.1 initial release) - * 0.40 08/27/96 - * - * Author: Michael Temari, - */ - -#include -#include -#include -#include - -#include "ftp.h" -#include "local.h" -#include "file.h" -#include "other.h" -#include "net.h" - -FILE *fpcommin; -FILE *fpcommout; - -int linkopen; -int loggedin; -int type; -int format; -int mode; -int structure; -int passive; -int atty; - -int cmdargc; -char *cmdargv[NUMARGS]; - -char reply[1024]; - -_PROTOTYPE(static int makeargs, (char *buff)); -_PROTOTYPE(int DOhelp, (void)); -_PROTOTYPE(int main, (int argc, char *argv[])); - -static int makeargs(buff) -char *buff; -{ -char *p; -int i; - - for(i = 0; i < NUMARGS; i++) - cmdargv[i] = (char *)0; - - p = buff + strlen(buff) - 1; - while(p != buff) - if(*p == '\r' || *p == '\n' || isspace(*p)) - *p-- = '\0'; - else - break; - - p = buff; - cmdargc = 0; - while(cmdargc < NUMARGS) { - while(*p && isspace(*p)) - p++; - if(*p == '\0') - break; - cmdargv[cmdargc++] = p; - while(*p && !isspace(*p)) { - if(cmdargc == 1) - *p = tolower(*p); - p++; - } - if(*p == '\0') - break; - *p = '\0'; - p++; - } -} - -int readline(prompt, buff, len) -char *prompt; -char *buff; -int len; -{ - printf(prompt); fflush(stdout); - - if(fgets(buff, len, stdin) == (char *)NULL) { - printf("\nEnd of file on input!\n"); - exit(1); - } - - *strchr(buff, '\n') = 0; - - if(!atty) { - printf("%s\n", buff); - fflush(stdout); - } - - return(0); -} - -int DOgetreply() -{ -char *p; -char buff[6]; -int s; -int firsttime; - - do { - firsttime = 1; - do { - if(fgets(reply, sizeof(reply), fpcommin) == (char *)0) - return(-1); - p = reply + strlen(reply) - 1; - while(p != reply) - if(*p == '\r' || *p == '\n' || isspace(*p)) - *p-- = '\0'; - else - break; - printf("%s\n", reply); fflush(stdout); - if(firsttime) { - firsttime = 0; - strncpy(buff, reply, 4); - buff[3] = ' '; - } - } while(strncmp(reply, buff, 3) || reply[3] == '-'); - s = atoi(buff); - } while(s < 200 && s != 125 & s != 150); - - return(s); -} - -int DOcmdcheck() -{ - if(!linkopen) { - printf("You must \"OPEN\" a connection first.\n"); - return(1); - } - - if(!loggedin) { - printf("You must login first.\n"); - return(1); - } - - return(0); -} - -int DOcommand(ftpcommand, ftparg) -char *ftpcommand; -char *ftparg; -{ - if(*ftparg) - fprintf(fpcommout, "%s %s\r\n", ftpcommand, ftparg); - else - fprintf(fpcommout, "%s\r\n", ftpcommand); - - fflush(fpcommout); - - return(DOgetreply()); -} - -int DOhelp() -{ -char junk[10]; - - printf("Command: Description\n"); - printf("! Escape to a shell\n"); - printf("append Append a file to remote host\n"); - printf("ascii Set file transfer mode to ascii\n"); - printf("binary Set file transfer mode to binary\n"); - printf("bye Close connection and exit\n"); - printf("cd Change directory on remote host\n"); - printf("close Close connection\n"); - printf("del Remove file on remote host\n"); - printf("dir Display long form remote host directory listing\n"); - printf("exit Close connection and exit\n"); - printf("get Retrieve a file from remote host\n"); - printf("help Display this text\n"); - printf("lcd Change directory on local host\n"); - printf("ldir Display long form local host directory listing\n"); - printf("lls Display local host directory listing\n"); - printf("lmkdir Create directory on local host\n"); - printf("lpwd Display current directory on local host\n"); - printf("lrmdir Remove directory on local host\n"); - printf("ls Display remote host directory listing\n"); - printf("mget Retrieve multiple files from remote host\n"); - printf("mkdir Create directory on remote host\n"); - printf("mod Get file modification time\n"); - - readline("Press ENTER to continue... ", junk, sizeof(junk)); - - printf("mput Send multiple files to remote host\n"); - printf("noop Send the ftp NOOP command\n"); - printf("open Open connection to remote host\n"); - printf("pass Enter remote user password\n"); - printf("passive Toggle passive mode\n"); - printf("put Send a file to remote host\n"); - printf("putu Send a file to remote host(unique)\n"); - printf("pwd Display current directory on remote host\n"); - printf("quit Close connection and exit\n"); - printf("quote Send raw ftp command to remote host\n"); - printf("reget Restart a partial file retrieve from remote host\n"); - printf("remotehelp Display ftp commands implemented on remote host\n"); - printf("reput Restart a partial file send to remote host\n"); - printf("rm Remove file on remote host\n"); - printf("rmdir Remove directory on remote host\n"); - printf("site Send a site specific command\n"); - printf("size Get file size information\n"); - printf("status Get connection/file status information\n"); - printf("system Get remote system type information\n"); - printf("user Enter remote user information\n"); - - return(0); -} - -struct commands { - char *name; - _PROTOTYPE(int (*func), (void)); -}; - -static struct commands commands[] = { - "!", DOlshell, - "append", DOappe, - "ascii", DOascii, - "binary", DObinary, - "bin", DObinary, - "bye", DOquit, - "cd", DOcd, - "close", DOclose, - "del", DOdelete, - "dir", DOlist, - "exit", DOquit, - "get", DOretr, - "help", DOhelp, - "lcd", DOlcd, - "ldir", DOllist, - "lls", DOlnlst, - "lmkdir", DOlmkdir, - "lpwd", DOlpwd, - "lrmdir", DOlrmdir, - "ls", DOnlst, - "mget", DOMretr, - "mkdir", DOmkdir, - "mod", DOmdtm, - "mput", DOMstor, - "noop", DOnoop, - "open", DOopen, - "pass", DOpass, - "passive", DOpassive, - "put", DOstor, - "putu", DOstou, - "pwd", DOpwd, - "quit", DOquit, - "quote", DOquote, - "reget", DOrretr, - "remotehelp", DOremotehelp, - "reput", DOrstor, - "rm", DOdelete, - "rmdir", DOrmdir, - "site", DOsite, - "size", DOsize, - "status", DOstat, - "system", DOsyst, - "user", DOuser, - "", (int (*)())0 -}; - -int main(argc, argv) -int argc; -char *argv[]; -{ -int s; -struct commands *cmd; -static char buffer[128]; - - NETinit(); - - FTPinit(); - - s = 0; - - if(argc > 1) { - sprintf(buffer, "open %s ", argv[1]); - makeargs(buffer); - s = DOopen(); - if(atty && s > 0) { - sprintf(buffer, "user"); - makeargs(buffer); - s = DOuser(); - } - } - - while(s >= 0) { - readline("ftp>", buffer, sizeof(buffer)); - makeargs(buffer); - if(cmdargc == 0) continue; - for(cmd = commands; *cmd->name != '\0'; cmd++) - if(!strcmp(cmdargv[0], cmd->name)) - break; - if(*cmd->name != '\0') - s = (*cmd->func)(); - else { - s = 0; - printf("Command \"%s\" not recognized.\n", cmdargv[0]); - } - } - - return(0); -} diff --git a/commands/ftp/ftp.h b/commands/ftp/ftp.h deleted file mode 100644 index b0c234511..000000000 --- a/commands/ftp/ftp.h +++ /dev/null @@ -1,36 +0,0 @@ -/* ftp.h - * - * This file is part of ftp. - * - * - * 01/25/96 Initial Release Michael Temari, - */ - -extern FILE *fpcommin; -extern FILE *fpcommout; - -extern int linkopen; -extern int loggedin; -extern int type; -extern int format; -extern int mode; -extern int structure; -extern int passive; -extern int atty; - -#define NUMARGS 10 -extern int cmdargc; -extern char *cmdargv[NUMARGS]; - -extern char reply[1024]; - -#define RETR 0 -#define STOR 1 - -#define TYPE_A 0 -#define TYPE_I 1 - -_PROTOTYPE(int readline, (char *prompt, char *buff, int len)); -_PROTOTYPE(int DOgetreply, (void)); -_PROTOTYPE(int DOcmdcheck, (void)); -_PROTOTYPE(int DOcommand, (char *ftpcommand, char *ftparg)); diff --git a/commands/ftp/local.c b/commands/ftp/local.c deleted file mode 100644 index 7f2143d9e..000000000 --- a/commands/ftp/local.c +++ /dev/null @@ -1,128 +0,0 @@ -/* local.c - * - * This file is part of ftp. - * - * - * 01/25/96 Initial Release Michael Temari, - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "ftp.h" -#include "local.h" - -static char line2[512]; - -_PROTOTYPE(static void dodir, (char *path, int full)); - -int DOlpwd() -{ - if(getcwd(line2, sizeof(line2)) == (char *)NULL) - printf("Could not determine local directory. %s\n", strerror(errno)); - else - printf("Current local directory: %s\n", line2); - - return(0); -} - -int DOlcd() -{ -char *path; -int s; - - path = cmdargv[1]; - - if(cmdargc < 2) { - readline("Path: ", line2, sizeof(line2)); - path = line2; - } - - if(chdir(path)) - printf("Could not change local directory. %s\n", strerror(errno)); - else - DOlpwd(); - - return(0); -} - -int DOlmkdir() -{ -char *path; -int s; - - path = cmdargv[1]; - - if(cmdargc < 2) { - readline("Directory: ", line2, sizeof(line2)); - path = line2; - } - - if(mkdir(path, 0777)) - printf("Could not make directory %s. %s\n", path, strerror(errno)); - else - printf("Directory created.\n"); - - return(0); -} - -int DOlrmdir() -{ -char *path; -int s; - - path = cmdargv[1]; - - if(cmdargc < 2) { - readline("Directory: ", line2, sizeof(line2)); - path = line2; - } - - if(rmdir(path)) - printf("Could not remove directory %s. %s\n", path, strerror(errno)); - else - printf("Directory removed.\n"); - - return(0); -} - -int DOllist(void) -{ - dodir(".", 1); -} - -int DOlnlst(void) -{ - dodir(".", 0); -} - -int DOlshell(void) -{ - system("$SHELL"); -} - -static void dodir(path, full) -char *path; -int full; -{ -char cmd[128]; -static char name[32]; - - tmpnam(name); - - if(full) - sprintf(cmd, "ls -l %s > %s", path, name); - else - sprintf(cmd, "ls %s > %s", path, name); - - system(cmd); - sprintf(cmd, "more %s", name); - system(cmd); - sprintf(cmd, "rm %s", name); - system(cmd); -} diff --git a/commands/ftp/local.h b/commands/ftp/local.h deleted file mode 100644 index ceb70693f..000000000 --- a/commands/ftp/local.h +++ /dev/null @@ -1,15 +0,0 @@ -/* local.h - * - * This file is part of ftp. - * - * - * 01/25/96 Initial Release Michael Temari, - */ - -_PROTOTYPE(int DOlpwd, (void)); -_PROTOTYPE(int DOlcd, (void)); -_PROTOTYPE(int DOlmkdir, (void)); -_PROTOTYPE(int DOlrmdir, (void)); -_PROTOTYPE(int DOllist, (void)); -_PROTOTYPE(int DOlnlst, (void)); -_PROTOTYPE(int DOlshell, (void)); diff --git a/commands/ftp/net.c b/commands/ftp/net.c deleted file mode 100644 index c01b2d114..000000000 --- a/commands/ftp/net.c +++ /dev/null @@ -1,421 +0,0 @@ -/* net.c - * - * This file is part of ftp. - * - * - * 01/25/96 Initial Release Michael Temari, - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ftp.h" -#include "file.h" -#include "net.h" - -_PROTOTYPE(void donothing, (int sig)); - -static int ftpcomm_fd; -static ipaddr_t myip; -static ipaddr_t hostip; -static char host[256]; -static int lpid; - -void NETinit() -{ -int s; -char *tcp_device; -int tcp_fd; -nwio_tcpconf_t nwio_tcpconf; - - /* All this just to get our ip address */ - - if((tcp_device = getenv("TCP_DEVICE")) == (char *)NULL) - tcp_device = TCP_DEVICE; - - tcp_fd = open(tcp_device, O_RDWR); - if(tcp_fd < 0) { - perror("ftp: Could not open tcp_device"); - exit(-1); - } - s = ioctl(tcp_fd, NWIOGTCPCONF, &nwio_tcpconf); - if(s < 0) { - perror("ftp: Could not get tcp configuration"); - exit(-1); - } - - myip = nwio_tcpconf.nwtc_locaddr; - - close(tcp_fd); -} - -int DOopen() -{ -nwio_tcpconf_t tcpconf; -nwio_tcpcl_t tcpcopt; -char *tcp_device; -tcpport_t port; -int s; -struct hostent *hp; -struct servent *servent; - - if(linkopen) { - printf("Use \"CLOSE\" to close the connection first.\n"); - return(0); - } - - if(cmdargc < 2) - readline("Host: ", host, sizeof(host)); - else - strncpy(host, cmdargv[1], sizeof(host)); - - if((servent = getservbyname("ftp", "tcp")) == (struct servent *)NULL) { - fprintf(stderr, "ftp: Could not find ftp tcp service\n"); - return(-1); - } - port = (tcpport_t)servent->s_port; - - hp = gethostbyname(host); - if (hp == (struct hostent *)NULL) { - hostip = (ipaddr_t)0; - printf("Unresolved host %s\n", host); - return(0); - } else - memcpy((char *) &hostip, (char *) hp->h_addr, hp->h_length); - - /* This HACK allows the server to establish data connections correctly */ - /* when using the loopback device to talk to ourselves */ - if(hostip == inet_addr("127.0.0.1")) - hostip = myip; - - if((tcp_device = getenv("TCP_DEVICE")) == NULL) - tcp_device = "/dev/tcp"; - - if((ftpcomm_fd = open(tcp_device, O_RDWR)) < 0) { - perror("ftp: open error on tcp device"); - return(-1); - } - - tcpconf.nwtc_flags = NWTC_LP_SEL | NWTC_SET_RA | NWTC_SET_RP; - tcpconf.nwtc_remaddr = hostip; - tcpconf.nwtc_remport = port; - - s = ioctl(ftpcomm_fd, NWIOSTCPCONF, &tcpconf); - if(s < 0) { - perror("ftp: ioctl error on NWIOSTCPCONF"); - close(ftpcomm_fd); - return(s); - } - - tcpcopt.nwtcl_flags = 0; - - s = ioctl(ftpcomm_fd, NWIOTCPCONN, &tcpcopt); - if(s < 0) { - perror("ftp: ioctl error on NWIOTCPCONN"); - close(ftpcomm_fd); - return(s); - } - - s = ioctl(ftpcomm_fd, NWIOGTCPCONF, &tcpconf); - if(s < 0) { - perror("ftp: ioctl error on NWIOGTCPCONF"); - close(ftpcomm_fd); - return(s); - } - - fpcommin = fdopen(ftpcomm_fd, "r"); - fpcommout = fdopen(ftpcomm_fd, "w"); - - s = DOgetreply(); - - if(s < 0) { - fclose(fpcommin); - fclose(fpcommout); - close(ftpcomm_fd); - return(s); - } - - if(s != 220) { - fclose(fpcommin); - fclose(fpcommout); - close(ftpcomm_fd); - return(0); - } - - linkopen = 1; - - return(s); -} - -int DOclose() -{ - if(!linkopen) { - printf("You can't close a connection that isn't open.\n"); - return(0); - } - - fclose(fpcommin); - fclose(fpcommout); - close(ftpcomm_fd); - - linkopen = 0; - loggedin = 0; - - return(0); -} - -int DOquit() -{ -int s; - - if(linkopen) { - s = DOcommand("QUIT", ""); - s = DOclose(); - } - - printf("FTP done.\n"); - - exit(0); -} - -void donothing(sig) -int sig; -{ -} - -int DOdata(datacom, file, direction, fd) -char *datacom; -char *file; -int direction; /* RETR or STOR */ -int fd; -{ -nwio_tcpconf_t tcpconf; -nwio_tcpcl_t tcplopt, tcpcopt; -char *tcp_device; -int ftpdata_fd; -char *buff; -ipaddr_t ripaddr; -tcpport_t rport; -static tcpport_t lport = HTONS(0xF000); -int s; -int i; -int cs; -int pfd[2]; -char dummy; -char port[32]; - - ripaddr = hostip; - rport = HTONS(20); - - /* here we set up a connection to listen on if not passive mode */ - /* otherwise we use this to connect for passive mode */ - - if((tcp_device = getenv("TCP_DEVICE")) == NULL) - tcp_device = "/dev/tcp"; - - if((ftpdata_fd = open(tcp_device, O_RDWR)) < 0) { - perror("ftp: open error on tcp device"); - return(-1); - } - - if(passive) { - s = DOcommand("PASV", ""); - if(s != 227) { - close(ftpdata_fd); - return(s); - } - /* decode host and port */ - buff = reply; - while(*buff && (*buff != '(')) buff++; - buff++; - ripaddr = (ipaddr_t)0; - for(i = 0; i < 4; i++) { - ripaddr = (ripaddr << 8) + (ipaddr_t)atoi(buff); - if((buff = strchr(buff, ',')) == (char *)0) { - printf("Could not parse PASV reply\n"); - return(-1); - } - buff++; - } - rport = (tcpport_t)atoi(buff); - if((buff = strchr(buff, ',')) == (char *)0) { - printf("Could not parse PASV reply\n"); - return(-1); - } - buff++; - rport = (rport << 8) + (tcpport_t)atoi(buff); - ripaddr = ntohl(ripaddr); - rport = ntohs(rport); - } - - for (;;) { - tcpconf.nwtc_flags = NWTC_SET_RA | NWTC_SET_RP; - if (passive || ntohs(lport) >= 0xF000) { - tcpconf.nwtc_flags |= NWTC_LP_SEL; - } else { - /* For no good reason Sun hosts don't like it if they have to - * connect to the same port twice in a short time... - */ - lport = htons(ntohs(lport) + 1); - tcpconf.nwtc_flags |= NWTC_LP_SET; - tcpconf.nwtc_locport = lport; - } - - tcpconf.nwtc_remaddr = ripaddr; - tcpconf.nwtc_remport = rport; - - s = ioctl(ftpdata_fd, NWIOSTCPCONF, &tcpconf); - if(s < 0) { - if (errno == EADDRINUSE) continue; - perror("ftp: ioctl error on NWIOSTCPCONF"); - close(ftpdata_fd); - return(s); - } - break; - } - - s = ioctl(ftpdata_fd, NWIOGTCPCONF, &tcpconf); - if(s < 0) { - perror("ftp: ioctl error on NWIOGTCPCONF"); - close(ftpdata_fd); - return(s); - } - lport = tcpconf.nwtc_locport; - - if(passive) { - tcplopt.nwtcl_flags = 0; - s = ioctl(ftpdata_fd, NWIOTCPCONN, &tcpcopt); - if(s < 0) { - perror("ftp: error on ioctl NWIOTCPCONN"); - close(ftpdata_fd); - return(0); - } - s = ioctl(ftpdata_fd, NWIOGTCPCONF, &tcpconf); - if(s < 0) { - perror("ftp: error on ioctl NWIOGTCPCONF"); - close(ftpdata_fd); - return(0); - } - } else { - tcplopt.nwtcl_flags = 0; - - if (pipe(pfd) < 0) { - perror("ftp: could not create a pipe"); - return(s); - } - lpid = fork(); - if(lpid < 0) { - perror("ftp: could not fork listener"); - close(ftpdata_fd); - close(pfd[0]); - close(pfd[1]); - return(s); - } else if(lpid == 0) { - close(pfd[0]); - signal(SIGALRM, donothing); - alarm(15); - close(pfd[1]); - s = ioctl(ftpdata_fd, NWIOTCPLISTEN, &tcplopt); - alarm(0); - if(s < 0) - if(errno == EINTR) - exit(1); /* timed out */ - else - exit(-1); /* error */ - else - exit(0); /* connection made */ - } - /* Wait for the pipe to close, then the listener is ready (almost). */ - close(pfd[1]); - (void) read(pfd[0], &dummy, 1); - close(pfd[0]); - while(1) { - signal(SIGALRM, donothing); - alarm(1); - s = ioctl(ftpdata_fd, NWIOGTCPCONF, &tcpconf); - alarm(0); - if(s == -1) break; - } - } - -#define hiword(x) ((u16_t)((x) >> 16)) -#define loword(x) ((u16_t)(x & 0xffff)) -#define hibyte(x) (((x) >> 8) & 0xff) -#define lobyte(x) ((x) & 0xff) - - if(!passive) { - sprintf(port, "%u,%u,%u,%u,%u,%u", - hibyte(hiword(ntohl(myip))), lobyte(hiword(ntohl(myip))), - hibyte(loword(ntohl(myip))), lobyte(loword(ntohl(myip))), - hibyte(ntohs(lport)), lobyte(ntohs(lport))); - s = DOcommand("PORT", port); - if(s != 200) { - close(ftpdata_fd); - kill(lpid, SIGKILL); - return(s); - } - } - - s = DOcommand(datacom, file); - if(s == 125 || s == 150) { - if(!passive) { - while(1) { - s = wait(&cs); - if(s < 0 || s == lpid) - break; - } - if(s < 0) { - perror("wait error:"); - close(ftpdata_fd); - kill(lpid, SIGKILL); - return(s); - } - if((cs & 0x00ff)) { - printf("Child listener failed %04x\n", cs); - close(ftpdata_fd); - return(-1); - } - cs = (cs >> 8) & 0x00ff; - if(cs == 1) { - printf("Child listener timed out\n"); - return(DOgetreply()); - } else if(cs) { - printf("Child listener returned %02x\n", cs); - close(ftpdata_fd); - return(-1); - } - } - switch(direction) { - case RETR: - s = recvfile(fd, ftpdata_fd); - break; - case STOR: - s = sendfile(fd, ftpdata_fd); - break; - } - close(ftpdata_fd); - s = DOgetreply(); - } else { - if(!passive) - kill(lpid, SIGKILL); - close(ftpdata_fd); - } - - return(s); -} diff --git a/commands/ftp/net.h b/commands/ftp/net.h deleted file mode 100644 index fa196be3a..000000000 --- a/commands/ftp/net.h +++ /dev/null @@ -1,13 +0,0 @@ -/* net.h - * - * This file is part of ftp. - * - * - * 01/25/96 Initial Release Michael Temari, - */ - -_PROTOTYPE(void NETinit, (void)); -_PROTOTYPE(int DOopen, (void)); -_PROTOTYPE(int DOclose, (void)); -_PROTOTYPE(int DOquit, (void)); -_PROTOTYPE(int DOdata, (char *datacom, char *file, int direction, int fd)); diff --git a/commands/ftp/other.c b/commands/ftp/other.c deleted file mode 100644 index 249797c00..000000000 --- a/commands/ftp/other.c +++ /dev/null @@ -1,163 +0,0 @@ -/* other.c by Michael Temari 06/21/92 - * - * ftp An ftp client program for use with TNET. - * - * Author: Michael Temari, - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "ftp.h" -#include "other.h" - -void FTPinit() -{ - linkopen = 0; - loggedin = 0; - type = TYPE_A; - format = 0; - mode = 0; - structure = 0; - passive = 0; - atty = isatty(0); -} - -int DOpass() -{ -int s; -struct termios oldtty, newtty; -char *pass; -char password[64]; - - if(!linkopen) { - printf("You must \"OPEN\" a connection first.\n"); - return(0); - } - - pass = cmdargv[1]; - - if(cmdargc < 2) { - tcgetattr(fileno(stdout), &oldtty); - newtty = oldtty; - newtty.c_lflag &= ~ECHO; - tcsetattr(fileno(stdout), TCSANOW, &newtty); - readline("Password: ", password, sizeof(password)); - tcsetattr(fileno(stdout), TCSANOW, &oldtty); - printf("\n"); - pass = password; - } - - s = DOcommand("PASS", pass); - - if(s == 230) - loggedin = 1; - - return(s); -} - -int DOuser() -{ -char *user; -int s; -char username[64]; - - if(!linkopen) { - printf("You must \"OPEN\" a connection first.\n"); - return(0); - } - - loggedin = 0; - - user = cmdargv[1]; - - if(cmdargc < 2) { - readline("Username: ", username, sizeof(username)); - user = username; - } - - s = DOcommand("USER", user); - - if(atty && s == 331) { - cmdargv[0] = "password"; - cmdargc = 1; - return(DOpass()); - } - - if(s == 230) - loggedin = 1; - - return(s); -} - -int DOnoop() -{ - if(DOcmdcheck()) - return(0); - - return(DOcommand("NOOP", "")); -} - -int DOpassive() -{ - passive = 1 - passive; - - printf("Passive mode is now %s\n", (passive ? "ON" : "OFF")); - - return(0); -} - -int DOsyst() -{ - if(DOcmdcheck()) - return(0); - - return(DOcommand("SYST", "")); -} - -int DOremotehelp() -{ - if(!linkopen) { - printf("You must \"OPEN\" a connection first.\n"); - return(0); - } - - return(DOcommand("HELP", "")); -} - -int DOquote() -{ -int i; -static char args[512]; - - args[0] = '\0'; - - for(i = 2; i < cmdargc; i++) { - if(i != 2) - strcat(args, " "); - strcat(args, cmdargv[i]); - } - - return(DOcommand(cmdargv[1], args)); -} - -int DOsite() -{ -int i; -static char args[512]; - - args[0] = '\0'; - - for(i = 1; i < cmdargc; i++) { - if(i != 1) - strcat(args, " "); - strcat(args, cmdargv[i]); - } - - return(DOcommand("SITE", args)); -} diff --git a/commands/ftp/other.h b/commands/ftp/other.h deleted file mode 100644 index 27e760e7a..000000000 --- a/commands/ftp/other.h +++ /dev/null @@ -1,17 +0,0 @@ -/* other.h - * - * This file is part of ftp. - * - * - * 01/25/96 Initial Release Michael Temari, - */ - -_PROTOTYPE(void FTPinit, (void)); -_PROTOTYPE(int DOpass, (void)); -_PROTOTYPE(int DOuser, (void)); -_PROTOTYPE(int DOnoop, (void)); -_PROTOTYPE(int DOpassive, (void)); -_PROTOTYPE(int DOsyst, (void)); -_PROTOTYPE(int DOremotehelp, (void)); -_PROTOTYPE(int DOquote, (void)); -_PROTOTYPE(int DOsite, (void)); diff --git a/commands/httpd/Makefile b/commands/httpd/Makefile deleted file mode 100644 index a5cc7f34d..000000000 --- a/commands/httpd/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -# Makefile for httpd -# -# 02/17/1996 Michael Temari -# 07/07/1996 Initial Release Michael Temari -# 12/29/2002 Michael Temari -# 07/07/2003 Al Woodhull -# - -CFLAGS= -O -D_MINIX -D_POSIX_SOURCE -DDAEMON=1 -#CFLAGS= -O -D_MINIX -D_POSIX_SOURCE -DDAEMON=1 -DDEBUG=9 -LDFLAGS=-i -BINDIR=/usr/local/bin - -HTTPD_OBJS= httpd.o utility.o request.o process.o reply.o \ - police.o cgiexec.o net.o config.o pass.o proxy.o -DIR2HTML_OBJS= dir2html.o - -all: httpd dir2html - -httpd: $(HTTPD_OBJS) - $(CC) $(LDFLAGS) -o $@ $(HTTPD_OBJS) - install -S 16kw $@ - -dir2html: $(DIR2HTML_OBJS) - $(CC) $(LDFLAGS) -o $@ $(DIR2HTML_OBJS) - install -S 8kw $@ - -clean: - rm -f httpd $(HTTPD_OBJS) dir2html $(DIR2HTML_OBJS) *.bak - -install: $(BINDIR)/httpd $(BINDIR)/in.httpd $(BINDIR)/dir2html - -tar: - tar cvf ../httpd.tar Makefile README *.c *.h *.sh *.conf *.mtype - -$(BINDIR)/httpd: httpd - install -cs -o bin $? $@ - -$(BINDIR)/in.httpd: $(BINDIR)/httpd - install -l $? $@ - -$(BINDIR)/dir2html: dir2html - install -cs -o bin $? $@ - -httpd.o: httpd.c http.h utility.h net.h config.h -utility.o: utility.c utility.h config.h -request.o: request.c http.h utility.h config.h -process.o: process.c http.h utility.h -reply.o: reply.c http.h utility.h net.h config.h -police.o: police.c http.h utility.h config.h pass.h -cgiexec.o: cgiexec.c http.h config.h -net.o: net.c net.h -config.o: config.c utility.h config.h -pass.o: pass.c pass.h -proxy.o: proxy.c http.h -dir2html.o: dir2html.c - -installman: - mkdir -p /usr/local/man/man5 - mkdir -p /usr/local/man/man8 - cp -p httpd.conf.5 http_status.5 /usr/local/man/man5 - cp -p httpd.8 /usr/local/man/man8 - makewhatis /usr/local/man - - diff --git a/commands/httpd/README b/commands/httpd/README deleted file mode 100644 index 04ab53e9d..000000000 --- a/commands/httpd/README +++ /dev/null @@ -1,242 +0,0 @@ -httpd documentation 7/16/96 by Michael Temari -updated 2003-07-05 by Al Woodhull - -DISCLAIMER: - -Use at own risk etc... - - -COMMENTS: - -Please send me any bug reports, comments, questions, etc... My email -address is Michael@TemWare.Com - - -BACKGROUND: - -httpd is a World Wide Web (WWW) server. I wrote it from scratch so -the setup and configuration will not be like other web servers though -hopefully by reading this document there will be no problems in getting -my web server up and running on your Minix system. - - -COMPILING: - -To compile httpd all you need to do is type "make" in the httpd source -directory. There should be no errors or warnings. If you should run -out of memory when compiling try adding the -m option to the CFLAGS -list in the Makefile. - - -INSTALLING: - -To install httpd all you need to do is type "make install" in the httpd -source directory. By default the place to install httpd is into -/usr/local/bin. If you would like to change this then change BINDIR in -the Makefile. Httpd will be linked to in.httpd, which is the preferred -name for a program started by the tcpd internet access control program. -The program dir2html is also installed -- this provides a directory -listing when a web client accesses a directory which does not contain a -file named index.html (or an alternative designated in /etc/httpd.conf). -The man pages are installed by typing "make installman". - -CONFIGURING: - -Before running httpd it must be configured. The name of the default -configuration file is /etc/httpd.conf or you may pass the configuration -file name to httpd. Upon starting up, httpd will parse the configuration -file and then process requests. This README file and the sample httpd.conf -may also help in configuring. The httpd.conf.5 man page presents the same -information for reference use. - - -The configuration file is an ascii file which consists of lines of the -following form: - -directive LWS [parameters separated by LWS] - -NOTE: LWS denotes Linear White Space which is spaces and/or tabs - -The following are valid configuration file directives: - serverroot user chroot logfile dbgfile dirsend direxec vhost auth - proxyauth vpath include mtype - -To make the file more readable, on directives which occupy multiple -lines you may omit the directive on lines after the first and begin -these lines with LWS. - - -serverroot path - -The serverroot directive sets the translation for // to the given path. - - -user username - -The user directive causes the server to run as the given username, otherwise -the server will run as whoever started it (normally root). - - -chroot directory - -The chroot directive causes the server to chroot to the given directory after -the configuration and log files have been opened. Normally this will be the -home directory of the given username in the user directive. -NOTE: /~user will be translated to the home directory of the given user - // will be translated to the serverroot directory -NOTE: if this directive is used then beware of the consequences. - - -logfile filename - -The logfile directive tells the server where to log http transactions. -NOTE: the file must exist to enable logging - - -dbgfile filename - -The dbgfile directive tells the server where to log debug http transactions. -NOTE: the file must exist to enable logging - -dirsend filelist - -The dirsend directive tells the server that when a directory is requested -that it should send the first file that it finds in the directory from the -filelist for the request. - - -direxec program - -The direxec directive tells the server that when a directory is requested -and no file is found from the dirsend directive that it should run the -given program. -NOTE: the program normally generates a directory listing on the fly -NOTE: the program access is considered X with no access restrictions. - - -vhost hostname VhostRoot - -vhost is for defining access for virtual hosts. If none are configured then -any host is accepted. If specified then access is only granted for requests -for hosts which are configured here. In the Vpath section below the /// gets -translated to the corresponding VhostRoot. - - -auth authname authdescription access [passwdfile [users]] - -The auth directive sets up different authorizations with the server. The -authname is the name given to the authorization and is case insensitive. -The authdescription is the description of the authorization and is what -the user will see when asked to enter a username and password. The -access is one or more of (rwx). R tells the server the url can be -read. W tells the server the url can be overwritten. X tells the server -that the url can and should be executed. Access is in addition to normal -unix security considerations. For instance a file that can be written to -that does not have the W access will have an error returned. The -passwdfile is the name of the passwdfile to validate users against. If -the passwdfile is given as '.' then the system password file will be used -which is /etc/passwd. If no passwdfile is given then no authorization is -allowed for anyone. If no users are given then any validated users is -authorized, otherwise only the given users are allowed. - - -proxyauth authname authdescription access [passwdfile [users]] - -proxyauth defines any access authorization to be used for Proxy access -authname = Same as auth above -authdescription = Same as auth above -access = Must be R to allow proxy -passwdfile = Same as auth above -users = Same as auth above - - -vpath from to [auth [access]] - -The vpath directive sets up url path translations and authorizations. A -requested url that matches from will be translated to to with the given -auth and access. If auth does not exist then the url will have no access. -If access is not given then the access is taken from the auth record (see -above). A '.' in place of the to means that the server should use a -translation from another vpath record, but associate the given auth and -access with the requested url. A '*' maybe at the end only of the from -which is a wildcard match. For example if the from has /AB* then any of -/ABCDEF or /AB or /ABmichael will match, but /AD or /a will not. The -requested url is first checked against each vpath record until an exact -match (meaning url match from and from had no '*') is found or the end of -the list. Therefore a wildcard match will match the last from is the list -in which it matched. -NOTE: if at the beginning of the to field - /~user will get translated to the home directory of the given user - // wile get translated to the serverroot directory - - -include filename - -The include directive tells the server to read configuration information -from the given filename. -NOTE: normally mtype directives are included from another file - - -mtype mimetype extensions - -The mtype directive tells the server what mimetype to associate with files -which have any of the given extensions. If no match is found then the file -will be treated as application/octet-stream. -NOTE: normally you get mtype directives in included file - - - -USAGE: - - httpd [-v|-t] [configuration-file] - -The -t tells the server to just parse the configuration file so that you -can test it to see if it is the way you want it. You may also pass the -name of your configuration file if it is not the default /etc/httpd.conf. - -The -v option prints the server version and then exits. - - -STARTING: - -First of all httpd is a server and therefore you will need to start it -with tcpd. Tcpd is a program which listens for incoming TCP connections -on the passed port and when a connection comes in it forks and starts the -given daemon program. Therefore to start httpd you use: - - tcpd http /usr/local/bin/in.httpd & - -You will more than likely have this line in your /etc/rc or /etc/rc.net -file so that whenever your system is restarted the web server will also -be started. The first parameter http is the port that tcpd is going -to be listening for connections on. Here http (which should be defined -in /etc/services as 80) is the standard port for a web server. The second -parameter is the program that tcpd will fork and exec when a connection -comes in. The program will then have its stdin and stderr connected to -the client Then the web server program will start running with the tcpd -program waiting for the next connection. Currently there is no ability to -limit the number of simultaneous web servers running. NOTE: At some point -I will be adding the ability for httpd to start itself without the need of -tcpd. That way httpd will already be in memory and have parsed its -configuration file. - -In Minix 2.0.3 and later versions you may use: - - daemonize tcpd http /usr/local/bin/in.httpd - -(daemonize is a shell function defined in /usr/etc/rc which starts programs -as daemons). - - -FINAL WORDS - -I wanted to get the server out as soon as possible so I hurried up and -created this document to help out. Hopefully it will HELP more than -it HURTS. If anyone is interested in writing man pages for httpd or any -of the other network programs please let me know. - - -Michael Temari -Michael@TemWare.Com - -Please note also the SECURITY document in this directory. (asw 2003-07-05) diff --git a/commands/httpd/SECURITY b/commands/httpd/SECURITY deleted file mode 100644 index d5bd97680..000000000 --- a/commands/httpd/SECURITY +++ /dev/null @@ -1,48 +0,0 @@ -SECURITY NOTE - -Al Woodhull 2003-07-05 - -Running a web server is fun, but it's also not without risks. If, like -many Minix users, you are a guest on someone else's network, you need -to be very careful to operate your server in ways that will not put -your system at risk or interfere with others on the net. Here are some -points to consider: - -- Be sure to touch /usr/adm/httpd.log (or whatever you specify as the log -file in httpd.conf) before you start your web server for the first time --- nothing will be logged if the log file does not exist. Then look at -your log file frequently and be alert for any unusual activity. - -- You may also want to be sure that tcpd is configured to operate in -PARANOID mode. That will enable logging of connection attempts and -allow you to use the serv.access (5) file to limit the kinds of -connections that your system allows. - -- If you enable proxy webserving, be very careful, it can be used by -people you don't know to visit sites that don't welcome visitors whose -identity is hidden. This may cause your network host and ultimately you -some unpleasantness. - -- The Minix httpd can also support CGI applications. These are also -dangerous -- a CGI application allows someone else to execute a program -on your computer. Make sure anything you allow this way cannot be -abused. Many security violations are due to effects of input that was not -expected by the original author of a program. - -- It's an understatement to say that Minix is not a well-known -operating system. There are not many Minix systems operating as -servers on the internet. A consequence of this is that there few, if -any, people engaged in finding ways to attack weaknesses in Minix. But -the idea of "security through obscurity" is deprecated by serious -computer security experts. Any operating system or program of any -degree of complexity is likely to have bugs or features that can be -exploited in ways the original programmers did not foresee. You can't -count on the "good guys" being the first ones to discover a risk. -There are two things you should be sure to do if you are running a -network server of any kind: - -(1) be alert for new versions of the program that may fix bugs -discovered by other users, and - -(2) be sure to report to the program author or maintainer anything you -observe that looks like a bug or a way the program can be misused. diff --git a/commands/httpd/build b/commands/httpd/build deleted file mode 100755 index 3ee5f0395..000000000 --- a/commands/httpd/build +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -make clean -make && make install diff --git a/commands/httpd/cgiexec.c b/commands/httpd/cgiexec.c deleted file mode 100644 index 856a51200..000000000 --- a/commands/httpd/cgiexec.c +++ /dev/null @@ -1,255 +0,0 @@ -/* cgiexec.c by Michael Temari 02/17/96 - * - * This file is part of httpd. - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * 02/08/2005 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "http.h" -#include "config.h" -#include "net.h" - -_PROTOTYPE(char **cgienv, (struct http_request *rq, struct http_reply *rp)); -_PROTOTYPE(static int addenv, (char *name, char *value, char **buf, int *len)); - -int cgiexec(rq, rp) -struct http_request *rq; -struct http_reply *rp; -{ -struct stat st; -char *prog; -int cmdpid; -int status; -char *argv[5]; -int ifds[2]; -int ofds[2]; -static char cmd[2048]; -char **cmdenv; -int dirflag = 0; - - if(stat(rp->realurl, &st)) { - if(errno == EACCES) - rp->status = HTTP_STATUS_FORBIDDEN; - else - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - return(-1); - } - - if((st.st_mode & S_IFMT) == S_IFDIR) - if(direxec != NULL) { - prog = direxec; dirflag = 1; - } else - return(0); - else - prog = rp->realurl; - - /* check if prog is allowed to be exec'd */ - if(!dirflag && !(rp->urlaccess & URLA_EXEC)) - return(0); - - /* if cannot exec mode then return */ - if( (st.st_mode & S_IXUSR) == 0 && - (st.st_mode & S_IXGRP) == 0 && - (st.st_mode & S_IXOTH) == 0 ) - return(0); - - if((cmdenv = cgienv(rq, rp)) == NULL) { - rp->status = HTTP_STATUS_SERVER_ERROR; - strcpy(rp->statusmsg, "Could not setup cgi environment"); - return(-1); - } - - argv[0] = prog; - argv[1] = rp->realurl; - argv[2] = rq->url; - argv[3] = (char *)NULL; - - if(pipe(ifds) < 0) { - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - return(-1); - } - - if(pipe(ofds) < 0) { - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - close(ifds[0]); close(ifds[1]); - return(-1); - } - - if((cmdpid = fork()) < 0) { - close(ifds[0]); close(ofds[0]); - close(ifds[1]); close(ofds[1]); - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - return(-1); - } - - /* We don't know how much data is going to be passed back */ - rp->size = 0; - - if(cmdpid == 0) { /* Child */ -#if 0 - if((cmdpid = fork()) < 0) { - close(ifds[0]); close(ofds[0]); - close(ifds[1]); close(ofds[1]); - exit(-1); - } - if(cmdpid != 0) { - close(ifds[0]); close(ofds[0]); - close(ifds[1]); close(ofds[1]); - exit(0); - } -#endif - setsid(); - close(ifds[0]); close(ofds[1]); - dup2(ofds[0], 0); - dup2(ifds[1], 1); - dup2(ifds[1], 2); - close(ifds[1]); close(ofds[0]); - execve(argv[0], argv, cmdenv); - exit(0); - } - -#if 0 - /* Get rid of Zombie child */ - (void) wait(&status); -#endif - - close(ifds[1]); close(ofds[0]); - - rp->fd = ifds[0]; - rp->ofd = ofds[1]; - rp->pid = cmdpid; - - if(rp->urlaccess & URLA_HEADERS) - rp->headers = -1; - - return(-1); -} - -char **cgienv(rq, rp) -struct http_request *rq; -struct http_reply *rp; -{ -static char buffer[4096]; -char *p, *p2; -char **e; -int len; -char temp[20]; - - p = buffer; - len = sizeof(buffer); - - if(addenv("PATH", "/usr/local/bin:/bin:/usr/bin", &p, &len)) return(NULL); - if(getenv("TZ") != (char *)NULL) - if(addenv("TZ", getenv("TZ"), &p, &len)) return(NULL); - - /* HACK - some of these are hardcoded and should not be MAT 3/17/96 */ - - /* HTTP_ */ - - if(addenv("SERVER_SOFTWARE", "Temari httpd/1.0", &p, &len)) return(NULL); - if(addenv("SERVER_NAME", myhostname, &p, &len)) return(NULL); - if(addenv("GATEWAY_INTERFACE", "CGI/1.1", &p, &len)) return(NULL); - if(addenv("SERVER_PROTOCOL", "HTTP/1.0", &p, &len)) return(NULL); - if(rq->port) - sprintf(temp, "%u", rq->port); - else - strcpy(temp, "80"); - if(addenv("SERVER_PORT", temp, &p, &len)) return(NULL); - switch(rq->method) { - case HTTP_METHOD_GET: - if(addenv("REQUEST_METHOD", "GET", &p, &len)) return(NULL); - break; - case HTTP_METHOD_POST: - if(addenv("REQUEST_METHOD", "POST", &p, &len)) return(NULL); - break; - case HTTP_METHOD_HEAD: - if(addenv("REQUEST_METHOD", "HEAD", &p, &len)) return(NULL); - break; - case HTTP_METHOD_PUT: - if(addenv("REQUEST_METHOD", "PUT", &p, &len)) return(NULL); - break; - default: - if(addenv("REQUEST_METHOD", "UNKNOWN", &p, &len)) return(NULL); - } - if(addenv("PATH_INFO", "?", &p, &len)) return(NULL); - if(addenv("PATH_TRANSLATED", "?", &p, &len)) return(NULL); - if(addenv("SCRIPT_NAME", rq->url, &p, &len)) return(NULL); - if(addenv("QUERY_STRING", rq->query, &p, &len)) return(NULL); - if(addenv("REMOTE_HOST", rmthostname, &p, &len)) return(NULL); - if(addenv("REMOTE_ADDR", rmthostaddr, &p, &len)) return(NULL); - if(rq->authuser != (char *)NULL) - if(addenv("AUTH_USER", rq->authuser, &p, &len)) return(NULL); - /* AUTH_TYPE */ - /* REMOTE_USER */ - /* REMOTE_IDENT */ - if(rq->method == HTTP_METHOD_POST) { - if(addenv("CONTENT_TYPE", "application/x-www-form-urlencoded", &p, &len)) return(NULL); - sprintf(temp, "%lu", rq->size); - if(addenv("CONTENT_LENGTH", temp, &p, &len)) return(NULL); - } - /* COOKIE */ - if(rq->cookie[0] != '\0') - if(addenv("COOKIE", rq->cookie, &p, &len)) return(NULL); - /* HOST */ - if(addenv("HOST", rq->host, &p, &len)) return(NULL); - - if(len < 1) return(NULL); - *p++ = '\0'; - - p2 = buffer; - e = (char **)p; - while(*p2) { - if(len < sizeof(e)) return(NULL); - len -= sizeof(e); - *e++ = p2; - while(*p2) p2++; - p2++; - } - if(len < sizeof(e)) return(NULL); - *e++ = NULL; - - return((char **)p); -} - -static int addenv(name, value, buf, len) -char *name; -char *value; -char **buf; -int *len; -{ -char *p; -int size; - - p = *buf; - - size = strlen(name)+1+strlen(value)+1; - - if(size > *len) - return(-1); - - sprintf(p, "%s=%s", name, value); - - p += size; - *buf = p; - *len -= size; - - return(0); -} diff --git a/commands/httpd/config.c b/commands/httpd/config.c deleted file mode 100644 index dce4ef849..000000000 --- a/commands/httpd/config.c +++ /dev/null @@ -1,813 +0,0 @@ -/* config.c by Michael Temari 02/26/96 - * - * This file is part of httpd. - * - * 02/26/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include - -#include "utility.h" -#include "config.h" - -struct mtype *mtype = NULL; -struct msufx *msufx = NULL; -struct vhost *vhost = NULL; -struct vpath *vpath = NULL; -struct dirsend *dirsend = NULL; -struct auth *auth = NULL; -struct auth *proxyauth = NULL; -char *direxec = NULL; -char *srvrroot = ""; -char *LogFile = NULL; -char *DbgFile = NULL; -char *User = NULL; -char *Chroot = NULL; - -_PROTOTYPE(static int doconfig, (char *cfg_file)); -_PROTOTYPE(static int doinclude, (char *parms[], int np)); -_PROTOTYPE(static int domtype, (char *parms[], int np)); -_PROTOTYPE(static struct auth *findauth, (char *name)); -_PROTOTYPE(static int dovhost, (char *parms[], int np)); -_PROTOTYPE(static int dovpath, (char *parms[], int np)); -_PROTOTYPE(static int dosrvrroot, (char *parms[], int np)); -_PROTOTYPE(static int dodirsend, (char *parms[], int np)); -_PROTOTYPE(static int dodirexec, (char *parms[], int np)); -_PROTOTYPE(static char *subvpath, (char *s)); -_PROTOTYPE(static int dologfile, (char *parms[], int np)); -_PROTOTYPE(static int dodbgfile, (char *parms[], int np)); -_PROTOTYPE(static int douser, (char *parms[], int np)); -_PROTOTYPE(static int dochroot, (char *parms[], int np)); -_PROTOTYPE(static int adduser, (struct auth *pauth, char *user)); -_PROTOTYPE(static int doauth, (char *parms[], int np)); -_PROTOTYPE(static int doproxyauth, (char *parms[], int np)); - -int readconfig(cfg_file, testing) -char *cfg_file; -int testing; -{ -int s; -char *cfg; -struct msufx *ps; -struct mtype *pt; -struct vhost *ph; -struct vpath *pv; -struct dirsend *pd; -struct auth *pa; - - cfg = HTTPD_CONFIG_FILE; - if(cfg_file != (char *)NULL) - if(*cfg_file) - cfg = cfg_file; - - s = doconfig(cfg); - - if(testing) { - printf("ServerRoot: %s\n", srvrroot); - printf("UserName: %s\n", User == NULL ? "" : User); - printf("Chroot: %s\n", Chroot == NULL ? "" : Chroot); - printf("LogFile: %s\n", LogFile == NULL ? "" : LogFile); - printf("DbgFile: %s\n", DbgFile == NULL ? "" : DbgFile); - printf("DirSend:"); - for(pd = dirsend; pd != NULL; pd = pd->next) - printf(" %s", pd->file); - printf("\n"); - printf("DirExec: %s\n", direxec == NULL ? "" : direxec); - for(ph = vhost; ph != NULL; ph = ph->next) - printf("VHost: %s %s\n", ph->hname, ph->root); - for(pa = auth; pa != NULL; pa = pa->next) - printf("Auth: %s %s %d %s\n", - pa->name, pa->desc, pa->urlaccess, pa->passwdfile); - for(pa = proxyauth; pa != NULL; pa = pa->next) - printf("ProxyAuth: %s %s %d %s\n", - pa->name, pa->desc, pa->urlaccess, pa->passwdfile); - for(pv = vpath; pv != NULL; pv = pv->next) - printf("Vpath: %s %s %s %d\n", - pv->from, pv->to, pv->auth->name, pv->urlaccess); - for(pt = mtype; pt != NULL; pt = pt->next) { - printf("MType: %s :", pt->mimetype); - for(ps = pt->msufx; ps != NULL; ps = ps->tnext) - printf(" '%s'", ps->suffix); - printf("\n"); - } - for(ps = msufx; ps != NULL; ps = ps->snext) - printf("Suffix: %s\t%s\n", ps->suffix, ps->mtype->mimetype); - } - - return(s); -} - -static int doconfig(cfg_file) -char *cfg_file; -{ -FILE *fp; -int np; -int s; -char *p; -char ltype[40]; -char *parms[30]; -static char buffer[2048]; - - if((fp = fopen(cfg_file, "r")) == (FILE *)NULL) { - fprintf(stderr, "httpd: Could not read %s config file.\n", cfg_file); - return(-1); - } - - *ltype = '\0'; - - while(fgets(buffer, sizeof(buffer), fp) != (char *)NULL) { - if(buffer[0] == '#') continue; /* skip comments */ - np = getparms(buffer, parms, sizeof(parms)/sizeof(parms[0])); - if(np == 0) continue; /* blank line */ - if(parms[0] == (char *)NULL) - parms[0] = ltype; - else { - p = parms[0]; - while(*p) *p++ = tolower(*p); - strncpy(ltype, parms[0], sizeof(ltype)); - } - s = 0; - if(!strcmp(parms[0], "mtype")) s = domtype(parms, np); - else - if(!strcmp(parms[0], "vhost")) s = dovhost(parms, np); - else - if(!strcmp(parms[0], "vpath")) s = dovpath(parms, np); - else - if(!strcmp(parms[0], "serverroot")) s = dosrvrroot(parms, np); - else - if(!strcmp(parms[0], "dirsend")) s = dodirsend(parms, np); - else - if(!strcmp(parms[0], "direxec")) s = dodirexec(parms, np); - else - if(!strcmp(parms[0], "logfile")) s = dologfile(parms, np); - else - if(!strcmp(parms[0], "dbgfile")) s = dodbgfile(parms, np); - else - if(!strcmp(parms[0], "user")) s = douser(parms, np); - else - if(!strcmp(parms[0], "chroot")) s = dochroot(parms, np); - else - if(!strcmp(parms[0], "auth")) s = doauth(parms, np); - else - if(!strcmp(parms[0], "proxyauth")) s = doproxyauth(parms, np); - else - if(!strcmp(parms[0], "include")) s = doinclude(parms, np); - else - fprintf(stderr, "httpd: Unknown directive: %s\n", parms[0]); - if(s) { - fprintf(stderr, "httpd: Error processing config file\n"); - fclose(fp); - return(-1); - } - } - - fclose(fp); - - return(0); -} - -static int doinclude(parms, np) -char *parms[]; -int np; -{ -char *p; - - if(np < 2) return(0); - - p = subvpath(parms[1]); - - return(doconfig(p)); -} - -static int domtype(parms, np) -char *parms[]; -int np; -{ -int i; -struct mtype *pt, *lpt, *newpt; -struct msufx *ps, *lps, *newps, *psend; - - if(np < 2) return(0); - - - /* check if this mime type already exists in the list */ - for(pt = mtype, lpt = NULL; pt != NULL; lpt = pt, pt = pt->next) - if(!strcmp(parms[1], pt->mimetype)) - break; - - if(pt == NULL) { /* not there so add it */ - newpt = malloc(sizeof(struct mtype)); - if(newpt == NULL) { - fprintf(stderr, "httpd: malloc failed in domtype\n"); - return(-1); - } - newpt->mimetype = malloc(strlen(parms[1])+1); - if(newpt->mimetype == NULL) { - fprintf(stderr, "httpd: malloc failed in domtype\n"); - return(-1); - } - strcpy(newpt->mimetype, parms[1]); - newpt->msufx = NULL; - newpt->next = NULL; - if(lpt == NULL) - mtype = newpt; - else - lpt->next = newpt; - } else - newpt = pt; - - /* find end of suffix list */ - for(ps = newpt->msufx, lps = NULL; ps != NULL; lps = ps, ps = ps->tnext) ; - psend = lps; - - /* if no suffix given then add empty suffix for default */ - if(np == 2) - strcpy(parms[np++], ""); - - /* add each suffix to the mime type */ - for(i = 2; i < np; i++) { - /* a suffix can only be for a single mime type */ - for(ps = msufx, lps = NULL; ps != NULL; lps = ps, ps = ps->snext) { - if(!strcmp(ps->suffix, parms[i])) { - fprintf(stderr, "httpd: Suffix already found\n"); - return(-1); - } - if(strlen(parms[i]) > strlen(ps->suffix)) break; - } - newps = malloc(sizeof(struct msufx)); - if(newps == NULL) { - fprintf(stderr, "httpd: malloc failed in domtype\n"); - return(-1); - } - newps->suffix = malloc(strlen(parms[i])+1); - if(newps->suffix == NULL) { - fprintf(stderr, "httpd: malloc failed in domtype\n"); - return(-1); - } - strcpy(newps->suffix, parms[i]); - newps->mtype = newpt; - newps->snext = NULL; - newps->tnext = NULL; - if(lps == NULL) { - msufx = newps; - newps->snext = ps; - } else { - lps->snext = newps; - newps->snext = ps; - } - if(psend == NULL) - newpt->msufx = newps; - else - psend->tnext = newps; - psend = newps; - } - - return(0); -} - -static struct auth *findauth(name) -char *name; -{ -char lname[80]; -char *p, *p2; -struct auth *a = NULL; - - if(sizeof(lname) < (strlen(name)+1)) { - fprintf(stderr, "httpd: lname too small in findauth\n"); - return(a); - } - p = name; p2 = lname; - while(*p) - *p2++ = tolower(*p++); - *p2 = '\0'; - - for(a = auth; a != NULL; a = a->next) - if(!strcmp(a->name, lname)) break; - - return(a); -} - -static int dovhost(parms, np) -char *parms[]; -int np; -{ -char *hname, *root; -struct vhost *ph, *lph, *newph; - - if(np < 2) return(0); - - hname = parms[1]; - - if(np < 3) - root = ""; - else - root = parms[2]; - - for(ph = vhost, lph = NULL; ph != NULL; lph = ph, ph = ph->next) - ; - - newph = malloc(sizeof(struct vhost)); - if(newph == NULL) { - fprintf(stderr, "httpd: malloc failed in dovhost\n"); - return(-1); - } - newph->hname = malloc(strlen(hname)+1); - if(newph->hname == NULL) { - fprintf(stderr, "httpd: malloc failed in dovhost\n"); - return(-1); - } - strcpy(newph->hname, hname); - - root = subvpath(root); - - newph->root = malloc(strlen(root)+1); - if(newph->root == NULL) { - fprintf(stderr, "httpd: malloc failed in dovhost\n"); - return(-1); - } - strcpy(newph->root, root); - - if(np > 3) - if(parms[3][0] != '#') { - fprintf(stderr, "httpd: junk at end of vhost line\n"); - return(-1); - } - - newph->next = NULL; - if(lph == NULL) { - vhost = newph; - newph->next = ph; - } else { - lph->next = newph; - newph->next = ph; - } - - return(0); -} - -static int dovpath(parms, np) -char *parms[]; -int np; -{ -char *from, *to; -struct vpath *pv, *lpv, *newpv; - - if(np < 3) return(0); - - from = parms[1]; - to = parms[2]; - - for(pv = vpath, lpv = NULL; pv != NULL; lpv = pv, pv = pv->next) - ; - - newpv = malloc(sizeof(struct vpath)); - if(newpv == NULL) { - fprintf(stderr, "httpd: malloc failed in dovpath\n"); - return(-1); - } - newpv->from = malloc(strlen(from)+1); - if(newpv->from == NULL) { - fprintf(stderr, "httpd: malloc failed in dovpath\n"); - return(-1); - } - strcpy(newpv->from, from); - - to = subvpath(to); - - newpv->to = malloc(strlen(to)+1); - if(newpv->to == NULL) { - fprintf(stderr, "httpd: malloc failed in dovpath\n"); - return(-1); - } - strcpy(newpv->to, to); - - newpv->auth = NULL; - newpv->urlaccess = -1; - - if(np > 3) - if(parms[3][0] != '#') { - newpv->auth = findauth(parms[3]); - if(np > 4) - if(parms[4][0] != '#') { - newpv->urlaccess = mkurlaccess(parms[4]); - if(np > 5) - if(parms[5][0] != '#') { - fprintf(stderr, "httpd: junk at end of vpath line\n"); - return(-1); - } - } - } - - newpv->next = NULL; - if(lpv == NULL) { - vpath = newpv; - newpv->next = pv; - } else { - lpv->next = newpv; - newpv->next = pv; - } - - return(0); -} - -static int dosrvrroot(parms, np) -char *parms[]; -int np; -{ -char *newroot; - - if(np < 2) return(0); - - newroot = subvpath(parms[1]); - - srvrroot = malloc(strlen(newroot)+1); - if(srvrroot == NULL) { - fprintf(stderr, "httpd: malloc failed in dosrvrroot\n"); - return(-1); - } - strcpy(srvrroot, newroot); - if(srvrroot[strlen(srvrroot)-1] == '/') - srvrroot[strlen(srvrroot)-1] = '\0'; - - return(0); -} - -static int dodirsend(parms, np) -char *parms[]; -int np; -{ -char *file; -int i; -struct dirsend *pd, *lpd, *npd; - - if(np < 2) return(0); - - /* find end of the list */ - for(pd = dirsend, lpd = NULL; pd != NULL; lpd = pd, pd = pd->next) ; - - for(i = 1; i < np; i++) { - file = parms[i]; - if(file[0] == '#') break; - npd = malloc(sizeof(struct dirsend)); - if(npd == NULL) { - fprintf(stderr, "httpd: malloc failed in dodirsend\n"); - return(-1); - } - npd->file = malloc(strlen(file)+1); - if(npd->file == NULL) { - fprintf(stderr, "httpd: malloc failed in dodirsend\n"); - return(-1); - } - strcpy(npd->file, file); - npd->next = NULL; - if(lpd == NULL) - dirsend = npd; - else - lpd->next = npd; - lpd = npd; - } - - return(0); -} - -static int dodirexec(parms, np) -char *parms[]; -int np; -{ -char *file; - - if(np < 2) return(0); - - if(direxec != NULL) { - fprintf(stderr, "httpd: Error direxec line already present\n"); - return(-1); - } - - file = subvpath(parms[1]); - - direxec = malloc(strlen(file)+1); - - if(direxec == NULL) { - fprintf(stderr, "httpd: malloc failed in dodirexec\n"); - return(-1); - } - - strcpy(direxec, file); - - if(np > 2) - if(parms[2][0] != '#') { - fprintf(stderr, "httpd: garbage on end of direxec line\n"); - return(-1); - } - - return(0); -} - -static char *subvpath(s) -char *s; -{ -char *p, *p2; -int len; -static char buffer[1024]; -char user[80]; -struct passwd *pwd; - - /* replace beginning // with srvrroot */ - if(s[0] == '/' && s[1] == '/') - /* but not /// if we have VHOST's */ - if(vhost == NULL || s[2] != '/') { - strcpy(buffer, srvrroot); - strncat(buffer, s+1, sizeof(buffer) - strlen(buffer)); - buffer[sizeof(buffer)-1] = '\0'; - return(buffer); - } - - if(s[0] != '/' || s[1] != '~') return(s); - - /* replace beginning /~user with user home directory */ - p = s + 2; - p2 = user; - len = sizeof(user) - 1; - while(*p && *p != '/' && len-- > 0) *p2++ = *p++; - *p2 = '\0'; - if(*p != '\0' && *p != '/') return(s); - if((pwd = getpwnam(user)) == (struct passwd *)NULL) return(s); - strcpy(buffer, pwd->pw_dir); - strncat(buffer, p, sizeof(buffer) - strlen(buffer)); - buffer[sizeof(buffer)-1] = '\0'; - - return(buffer); -} - -static int dologfile(parms, np) -char *parms[]; -int np; -{ -char *p; - - if(np < 2) return(0); - - p = subvpath(parms[1]); - LogFile = malloc(strlen(p)+1); - if(LogFile == NULL) { - fprintf(stderr, "httpd: malloc failed in dologfile\n"); - return(-1); - } - strcpy(LogFile, p); - - return(0); -} - -static int dodbgfile(parms, np) -char *parms[]; -int np; -{ -char *p; - - if(np < 2) return(0); - - p = subvpath(parms[1]); - DbgFile = malloc(strlen(p)+1); - if(DbgFile == NULL) { - fprintf(stderr, "httpd: malloc failed in dodbgfile\n"); - return(-1); - } - strcpy(DbgFile, p); - - return(0); -} - -static int douser(parms, np) -char *parms[]; -int np; -{ - if(np < 2) return(0); - - User = malloc(strlen(parms[1])+1); - if(User == NULL) { - fprintf(stderr, "httpd: malloc failed in douser\n"); - return(-1); - } - strcpy(User, parms[1]); - - return(0); -} - -static int dochroot(parms, np) -char *parms[]; -int np; -{ -char *newroot; - - if(np < 2) return(0); - - newroot = subvpath(parms[1]); - - Chroot = malloc(strlen(newroot)+1); - if(Chroot == NULL) { - fprintf(stderr, "httpd: malloc failed in dochroot\n"); - return(-1); - } - strcpy(Chroot, newroot); - - return(0); -} - -static int adduser(pauth, user) -struct auth *pauth; -char *user; -{ -struct authuser *pa, *lpa, *newpa; - - for(pa = pauth->users, lpa = NULL; pa != NULL; lpa = pa, pa = pa->next) - ; - - newpa = malloc(sizeof(struct authuser)); - if(newpa == NULL) { - fprintf(stderr, "httpd: malloc failed in adduser\n"); - return(-1); - } - newpa->user = malloc(strlen(user)+1); - if(newpa->user == NULL) { - fprintf(stderr, "httpd: malloc failed in adduser\n"); - return(-1); - } - strcpy(newpa->user, user); - - newpa->next = NULL; - if(lpa == NULL) { - pauth->users = newpa; - newpa->next = pa; - } else { - lpa->next = newpa; - newpa->next = pa; - } - - return(0); -} - -static int doauth(parms, np) -char *parms[]; -int np; -{ -int i; -char *name, *desc, *pf; -char *p, *p2; -struct auth *pa, *lpa, *newpa; - - if(np < 3) return(0); - - name = parms[1]; - desc = parms[2]; - - for(pa = auth, lpa = NULL; pa != NULL; lpa = pa, pa = pa->next) - ; - - newpa = malloc(sizeof(struct auth)); - if(newpa == NULL) { - fprintf(stderr, "httpd: malloc failed in doauth\n"); - return(-1); - } - newpa->name = malloc(strlen(name)+1); - if(newpa->name == NULL) { - fprintf(stderr, "httpd: malloc failed in doauth\n"); - return(-1); - } - p = name; p2 = newpa->name; - while(*p) - *p2++ = tolower(*p++); - *p2 = '\0'; - - newpa->desc = malloc(strlen(desc)+1); - if(newpa->desc == NULL) { - fprintf(stderr, "httpd: malloc failed in doauth\n"); - return(-1); - } - strcpy(newpa->desc, desc); - - newpa->urlaccess = mkurlaccess(parms[3]); - newpa->passwdfile = NULL; - newpa->users = NULL; - - if(np > 4) - if(parms[4][0] != '#') { - if(!strcmp(parms[4], ".")) - pf = "/etc/passwd"; - else - pf = subvpath(parms[4]); - newpa->passwdfile = malloc(strlen(pf)+1); - if(newpa->passwdfile == NULL) { - fprintf(stderr, "httpd: malloc failed in doauth\n"); - return(-1); - } - strcpy(newpa->passwdfile, pf); - i = 5; - while(i < np) { - if(parms[i][0] == '#') - break; - if(adduser(newpa, parms[i])) - return(-1); - i++; - } - } - - newpa->next = NULL; - if(lpa == NULL) { - auth = newpa; - newpa->next = pa; - } else { - lpa->next = newpa; - newpa->next = pa; - } - - return(0); -} - -static int doproxyauth(parms, np) -char *parms[]; -int np; -{ -int i; -char *name, *desc, *pf; -char *p, *p2; -struct auth *pa, *lpa, *newpa; - - if(np < 3) return(0); - - name = parms[1]; - desc = parms[2]; - - if(proxyauth != (struct auth *)NULL) { - fprintf(stderr, "httpd: ProxyAuth defined multiple times using 1st only\n"); - return(0); - } - - for(pa = proxyauth, lpa = NULL; pa != NULL; lpa = pa, pa = pa->next) - ; - - newpa = malloc(sizeof(struct auth)); - if(newpa == NULL) { - fprintf(stderr, "httpd: malloc failed in doproxyauth\n"); - return(-1); - } - newpa->name = malloc(strlen(name)+1); - if(newpa->name == NULL) { - fprintf(stderr, "httpd: malloc failed in doproxyauth\n"); - return(-1); - } - p = name; p2 = newpa->name; - while(*p) - *p2++ = tolower(*p++); - *p2 = '\0'; - - newpa->desc = malloc(strlen(desc)+1); - if(newpa->desc == NULL) { - fprintf(stderr, "httpd: malloc failed in doproxyauth\n"); - return(-1); - } - strcpy(newpa->desc, desc); - - newpa->urlaccess = mkurlaccess(parms[3]); - newpa->passwdfile = NULL; - newpa->users = NULL; - - if(np > 4) - if(parms[4][0] != '#') { - if(!strcmp(parms[4], ".")) - pf = "/etc/passwd"; - else - pf = subvpath(parms[4]); - newpa->passwdfile = malloc(strlen(pf)+1); - if(newpa->passwdfile == NULL) { - fprintf(stderr, "httpd: malloc failed in doauth\n"); - return(-1); - } - strcpy(newpa->passwdfile, pf); - i = 5; - while(i < np) { - if(parms[i][0] == '#') - break; - if(adduser(newpa, parms[i])) - return(-1); - i++; - } - } - - newpa->next = NULL; - if(lpa == NULL) { - proxyauth = newpa; - newpa->next = pa; - } else { - lpa->next = newpa; - newpa->next = pa; - } - - return(0); -} diff --git a/commands/httpd/config.h b/commands/httpd/config.h deleted file mode 100644 index cf5891be4..000000000 --- a/commands/httpd/config.h +++ /dev/null @@ -1,84 +0,0 @@ -/* config.h - * - * This file is part of httpd. - * - * 02/26/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * 07/04/2003 Al Woodhull - * 02/08/2005 Michael Temari - * - */ - -#define VERSION "Minix httpd 0.994" - -struct authuser { - char *user; - struct authuser *next; -}; - -struct auth { - char *name; - char *desc; - int urlaccess; - char *passwdfile; - struct authuser *users; - struct auth *next; -}; - -struct msufx { - char *suffix; - struct mtype *mtype; - struct msufx *snext; - struct msufx *tnext; -}; - -struct mtype { - char *mimetype; - struct msufx *msufx; - struct mtype *next; -}; - -struct vhost { - char *hname; - char *root; - struct vhost *next; -}; - -struct vpath { - char *from; - char *to; - struct auth *auth; - int urlaccess; - struct vpath *next; -}; - -struct dirsend { - char *file; - struct dirsend *next; -}; - -/* urlaccess bits */ - -#define URLA_READ 1 -#define URLA_WRITE 2 -#define URLA_EXEC 4 -#define URLA_HEADERS 8 - -#define HTTPD_CONFIG_FILE "/etc/httpd.conf" - -_PROTOTYPE(int readconfig, (char *cfg_file, int testing)); - -extern struct mtype *mtype; -extern struct msufx *msufx; -extern struct vhost *vhost; -extern struct vpath *vpath; -extern struct dirsend *dirsend; -extern struct auth *auth; -extern struct auth *proxyauth; -extern char *direxec; -extern char *srvrroot; -extern char *LogFile; -extern char *DbgFile; -extern char *User; -extern char *Chroot; diff --git a/commands/httpd/dir2html.c b/commands/httpd/dir2html.c deleted file mode 100644 index 36634d68a..000000000 --- a/commands/httpd/dir2html.c +++ /dev/null @@ -1,187 +0,0 @@ -/* dir2html.c by Michael Temari 3/3/96 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct namelist { /* Obviously a list of names. */ - struct namelist *next; - char name[1]; -} namelist_t; - -_PROTOTYPE(static void sort, (namelist_t **anl)); -_PROTOTYPE(static namelist_t *collect, (char *dir)); -_PROTOTYPE(int main, (int argc, char *argv[])); - -static void sort(anl) -namelist_t **anl; -/* A stable mergesort disguised as line noise. Must be called like this: - * if (L != NULL && L->next != NULL) sort(&L); - */ -{ - /* static */ namelist_t *nl1, **mid; /* Need not be local */ - namelist_t *nl2; - - nl1 = *(mid = &(*anl)->next); - do { - if ((nl1 = nl1->next) == NULL) break; - mid = &(*mid)->next; - } while ((nl1 = nl1->next) != NULL); - - nl2 = *mid; - *mid = NULL; - - if ((*anl)->next != NULL) sort(anl); - if (nl2->next != NULL) sort(&nl2); - - nl1 = *anl; - for (;;) { - if (strcmp(nl1->name, nl2->name) <= 0) { - if ((nl1 = *(anl = &nl1->next)) == NULL) { - *anl = nl2; - break; - } - } else { - *anl = nl2; - nl2 = *(anl = &nl2->next); - *anl = nl1; - if (nl2 == NULL) break; - } - } -} - -static namelist_t *collect(dir) -char *dir; -/* Return a sorted list of directory entries. Returns null with errno != 0 - * on error. - */ -{ - namelist_t *names, **pn = &names; - DIR *dp; - struct dirent *entry; - - if ((dp = opendir(dir)) == NULL) return NULL; - - while ((entry = readdir(dp)) != NULL) { - if (strcmp(entry->d_name, ".") == 0) continue; - *pn = malloc(offsetof(namelist_t, name) + strlen(entry->d_name) + 1); - if (*pn == NULL) { - closedir(dp); - errno = ENOMEM; - return NULL; - } - strcpy((*pn)->name, entry->d_name); - pn = &(*pn)->next; - } - closedir(dp); - *pn = NULL; - if (names != NULL && names->next != NULL) sort(&names); - errno = 0; - return names; -} - -int main(argc, argv) -int argc; -char *argv[]; -{ - namelist_t *np; - char *rpath, *vpath; - static char cwd[1024]; - static char work[64]; - char *filename; - struct stat st; - struct tm *tmp; - static char month[][4] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", - }; - - if(argc > 1) { - rpath = argv[1]; - if (chdir(rpath) < 0) { - fprintf(stderr, "dir2html: %s: %s\n", rpath, strerror(errno)); - return(-1); - } - } else { - if(getcwd(cwd, sizeof(cwd)) == NULL) { - fprintf(stderr, "dir2html: getcwd(): %s", strerror(errno)); - return(-1); - } - rpath = cwd; - } - - if(argc > 2) { - vpath = argv[2]; - } else { - vpath = rpath; - } - - if ((np = collect(".")) == NULL && errno != 0) { - fprintf(stderr, "dir2html: %s: %s\n", vpath, strerror(errno)); - return(-1); - } - - printf("Index of %s\n", vpath); - printf("\n"); - printf("

Index of %s

\n", vpath); - - printf("
\n");
-    printf("%-22s  %-17s  %s\n", "Name", "Last modified", "Size/Type");
-    printf("
\n"); - - while (np != NULL) { - errno = 0; - filename = np->name; - np= np->next; - - if (stat(filename, &st) < 0) continue; - - printf("", - filename, S_ISDIR(st.st_mode) ? "/" : ""); - sprintf(work, "%.23s%s", - filename, S_ISDIR(st.st_mode) ? "/" : ""); - if (strcmp(filename, "..") == 0) strcpy(work, "Parent Directory"); - printf("%-22.22s%s", - work, strlen(work) > 22 ? ">" : " "); - tmp = localtime(&st.st_mtime); - printf(" %02d %s %d %02d:%02d", - tmp->tm_mday, month[tmp->tm_mon], 1900+tmp->tm_year, - tmp->tm_hour, tmp->tm_min); - if (S_ISREG(st.st_mode)) { - if (st.st_size < 10240) { - sprintf(work, "%lu ", (unsigned long) st.st_size); - } else - if (st.st_size < 10240 * 1024L) { - sprintf(work, "%luK", - ((unsigned long) st.st_size - 1) / 1024 + 1); - } else { - sprintf(work, "%luM", - ((unsigned long) st.st_size - 1) / (1024 * 1024L) + 1); - } - } else { - strcpy(work, - S_ISDIR(st.st_mode) ? "[dir]" : - S_ISBLK(st.st_mode) ? "[block]" : - S_ISCHR(st.st_mode) ? "[char]" : - S_ISFIFO(st.st_mode) ? "[pipe]" : - "[???]"); - } - printf(" %8s\n", work); - } - - printf("
\n"); - - printf("
\n"); - printf("Minix httpd 0.99\n"); - printf("\n"); - printf("\n"); - - return(0); -} diff --git a/commands/httpd/dir2html.sh b/commands/httpd/dir2html.sh deleted file mode 100755 index 5a4b101fb..000000000 --- a/commands/httpd/dir2html.sh +++ /dev/null @@ -1,42 +0,0 @@ -# dir2html.sh by Michael Temari 03/03/96 -# -#!/bin/sh -if [ $# != 0 ] -then -cd $1 -fi -dname=`pwd` -fdname=$2 -if [ $dname != / ] -then - dname=${dname}/ -fi -echo "" -echo "" -echo Directory of $fdname -echo "" -echo "

" -echo Directory of $fdname -echo "

" -echo "
" -# -ls $dname | -{ -while read fname -do -lname=$fdname$fname -echo "

" -echo -n "" -echo -n $fname -echo "
" -echo "

" -done -} -echo "
" -echo "
" -echo Directory Generated at `date` -echo "
" -echo "" -exit 0 diff --git a/commands/httpd/http.h b/commands/httpd/http.h deleted file mode 100644 index bf868f3ab..000000000 --- a/commands/httpd/http.h +++ /dev/null @@ -1,118 +0,0 @@ -/* http.h - * - * This file is part of httpd. - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ - -#define INDEX_FILE_NAME "index.html" - -#define HTTP_REQUEST_TYPE_SIMPLE 0 -#define HTTP_REQUEST_TYPE_FULL 1 -#define HTTP_REQUEST_TYPE_PROXY 2 - -#define HTTP_METHOD_UNKNOWN 0 -#define HTTP_METHOD_OPTIONS 1 -#define HTTP_METHOD_GET 2 -#define HTTP_METHOD_HEAD 3 -#define HTTP_METHOD_POST 4 -#define HTTP_METHOD_PUT 5 -#define HTTP_METHOD_PATCH 6 -#define HTTP_METHOD_COPY 7 -#define HTTP_METHOD_MOVE 8 -#define HTTP_METHOD_DELETE 9 -#define HTTP_METHOD_LINK 10 -#define HTTP_METHOD_UNLINK 11 -#define HTTP_METHOD_TRACE 12 -#define HTTP_METHOD_WRAPPED 13 - -#define HTTP_STATUS_OK 200 -#define HTTP_STATUS_CREATED 201 -#define HTTP_STATUS_ACCEPTED 202 -#define HTTP_STATUS_NO_CONTENT 204 -#define HTTP_STATUS_MOVED_PERM 301 -#define HTTP_STATUS_MOVED_TEMP 302 -#define HTTP_STATUS_NOT_MODIFIED 304 -#define HTTP_STATUS_USE_PROXY 305 -#define HTTP_STATUS_BAD_REQUEST 400 -#define HTTP_STATUS_UNAUTHORIZED 401 -#define HTTP_STATUS_FORBIDDEN 403 -#define HTTP_STATUS_NOT_FOUND 404 -#define HTTP_STATUS_METHOD_NOT_ALLOWED 405 -#define HTTP_STATUS_PROXY_AUTH_REQRD 407 -#define HTTP_STATUS_LENGTH_REQUIRED 411 -#define HTTP_STATUS_SERVER_ERROR 500 -#define HTTP_STATUS_NOT_IMPLEMENTED 501 -#define HTTP_STATUS_BAD_GATEWAY 502 -#define HTTP_STATUS_SERVICE_UNAVAILABLE 503 -#define HTTP_STATUS_GATEWAY_TIMEOUT 504 -#define HTTP_STATUS_UNSUPPORTED_VERSION 505 - -struct http_request { - int type; - int method; - char uri[256]; - char url[256]; - char query[256]; - char host[256]; - int port; - char useragent[256]; - int vmajor; - int vminor; - time_t ifmodsince; - off_t size; - time_t msgdate; - int keepopen; - char wwwauth[128]; - char authuser[128]; - char authpass[128]; - char cookie[128]; -}; - -struct http_reply { - int status; - char statusmsg[128]; - int keepopen; - int headers; - char *mtype; - char realurl[256]; - struct auth *auth; - int urlaccess; - off_t size; - time_t modtime; - int fd; - int ofd; - int pid; -}; - -/* from httpd.c */ - -extern FILE *stdlog; -extern FILE *dbglog; - -/* from reply.c */ - -_PROTOTYPE(int sendreply, (struct http_reply *rp, struct http_request *rq)); - -/* from request.c */ - -_PROTOTYPE(int getrequest, (struct http_request *rq)); - -/* from process.c */ - -_PROTOTYPE(int processrequest, (struct http_request *rq, struct http_reply *rp)); - -/* from police.c */ - -_PROTOTYPE(int police, (struct http_request *rq, struct http_reply *rp)); - -/* from cgiexec.c */ - -_PROTOTYPE(int cgiexec, (struct http_request *rq, struct http_reply *rp)); - -/* from proxy.c */ - -_PROTOTYPE(void proxy, (struct http_request *rq, struct http_reply *rp)); diff --git a/commands/httpd/http_status.5 b/commands/httpd/http_status.5 deleted file mode 100644 index 16791155f..000000000 --- a/commands/httpd/http_status.5 +++ /dev/null @@ -1,73 +0,0 @@ -.TH HTTP_STATUS 5 -.SH -http_status \- HTTP status numbers and their meanings -.SH DESCRIPTION -These are the HTTP status numbers defined in -.BI http.h -in the source directory, -.BI /usr/local/src/httpdxxx. -The message you see on your screen when a page cannot be accessed is -normally generated by your browser. -.P -HTTP_STATUS_OK 200 -.br -HTTP_STATUS_CREATED 201 -.br -HTTP_STATUS_ACCEPTED 202 -.br -HTTP_STATUS_NO_CONTENT 204 -.br -HTTP_STATUS_MOVED_PERM 301 -.br -HTTP_STATUS_MOVED_TEMP 302 -.br -HTTP_STATUS_NOT_MODIFIED 304 -.br -HTTP_STATUS_USE_PROXY 305 -.br -HTTP_STATUS_BAD_REQUEST 400 -.br -HTTP_STATUS_UNAUTHORIZED 401 -.br -HTTP_STATUS_FORBIDDEN 403 -.br -HTTP_STATUS_NOT_FOUND 404 -.br -HTTP_STATUS_METHOD_NOT_ALLOWED 405 -.br -HTTP_STATUS_PROXY_AUTH_REQRD 407 -.br -HTTP_STATUS_LENGTH_REQUIRED 411 -.br -HTTP_STATUS_SERVER_ERROR 500 -.br -HTTP_STATUS_NOT_IMPLEMENTED 501 -.br -HTTP_STATUS_BAD_GATEWAY 502 -.br -HTTP_STATUS_SERVICE_UNAVAILABLE 503 -.br -HTTP_STATUS_GATEWAY_TIMEOUT 504 -.br -HTTP_STATUS_UNSUPPORTED_VERSION 505 -.br - -.SH FILES -.TP 25n -.B /usr/local/src/httpdxxx/http.h -.SH "SEE ALSO" -The definitive source of information on the HTTP protocol is the -.B "World Wide Web Consortium" -web page at -.B http://www.w3c.org . -.P -A draft version of the HTTP 1.1 specification is available on the Minix1 -websites. For more information on status codes go to this URL: -.B http://minix1.hampshire.edu/http11.html#Status-Codes -.SH AUTHOR -The Minix httpd server was created by and is maintained by Michael Temari - -.br -This man page was compiled by Al Woodhull -.P -updated 2003-07-06 diff --git a/commands/httpd/httpd.8 b/commands/httpd/httpd.8 deleted file mode 100644 index 7d195b320..000000000 --- a/commands/httpd/httpd.8 +++ /dev/null @@ -1,104 +0,0 @@ -.TH HTTPD 8 -.SH NAME -httpd, in.httpd, dir2html \- a web server for Minix -.SH SYNOPSIS -.B httpd -.RB [\-t|\-v] -.RI [ config_file ] -.br -.B "tcpd http /usr/local/bin/in.httpd" -.br -.B dir2html -.RB [directory] -.SH DESCRIPTION -.B httpd -is a World Wide Web (WWW) server written by Michael Temari. It was -written from scratch so the setup and configuration will not be like -other web servers. -.P -.B in.httpd -is linked to -.B httpd. -This alternate name is used to indicate the program is a server that is -started by -.B tcpd, -a program which listens for incoming TCP connections on the passed -port (defined in -.BI /etc/services ). -When a connection comes in -.B tcpd -forks and starts the given daemon program, after possibly checking for access -restrictions and logging the connection. Therefore to start -.B httpd -you use: -.br -.B "tcpd http /usr/local/bin/in.httpd &" -.br -or -.br -.B "daemonize tcpd http /usr/local/bin/in.httpd" -.P -.B (daemonize -is a shell function defined in -.BI/usr/etc/rc -in Minix 2.0.3 and later releases which starts programs as daemons). -.P -.B dir2html -is an accessory program that produces a directory listing formatted as -web page for the current directory or for a directory specified as an -argument. It is called by -.B httpd -when a web client references a directory that includes no index.html -file (or whatever alternative to index.html that may be defined in -/etc/httpd.conf). Since it writes to standard output it may also be called -as a standalone program. -.P -Options for -.B httpd -are: -.SH OPTIONS -.TP -.B \-t -This tells the server to parse the configuration file so that you can -see if it is the way you want it. You may also pass the name of your -configuration file if it is not the default /etc/httpd.conf. -.TP -.B \-v -Shows the server version, then exits. -.br -.IR config_file -normally /etc/httpd.conf -.SH FILES -.TP 25n -.B /etc/httpd.conf -The configuration file. -.P -.B /etc/httpd.mtype -Extension to configuration file defining MIME types. -.P -.B /usr/adm/httpd.log -Log file. The file must exist for logging to begin. -.SH "SEE ALSO" -.BR httpd.conf (5) -.br -.BR http_status (5) -.br -.BR serv.access (5) -.br -.BR tcpd (8) -.SH NOTES -Running a server exposed to the Internet is risky to the host system and -to the local network. Consult with the owner of your net before you go -public. Read the -.B SECURITY -document in the source directory. -.SH BUGS -None are known, but there are surely some unknown ones. Be careful! -.SH AUTHOR -The Minix httpd server was created by and is maintained by Michael Temari - -.br -This man page was compiled by Al Woodhull -.P -updated 2003-07-06 - diff --git a/commands/httpd/httpd.c b/commands/httpd/httpd.c deleted file mode 100644 index 5fc903aff..000000000 --- a/commands/httpd/httpd.c +++ /dev/null @@ -1,175 +0,0 @@ -/* httpd.c - * - * httpd A Server implementing the HTTP protocol. - * - * usage: tcpd http httpd & - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * 07/04/2003 Al Woodhull - * - */ - -#include -#include -#include -#include -#include -#include -#include "http.h" -#include "utility.h" -#include "net.h" -#include "config.h" - -FILE *stdlog = (FILE *)NULL; -FILE *dbglog = (FILE *)NULL; - -char umsg[80]; - -_PROTOTYPE(int main, (int argc, char *argv[])); - -struct http_request request; -struct http_reply reply; - -int main(argc, argv) -int argc; -char *argv[]; -{ -char *prog; -int opt_t; -char *cfg = (char *)NULL; -struct passwd *pwd; -int s; - - strcpy(umsg, "Usage: "); - strcat(umsg, argv[0]); - strcat(umsg, " [-t|v] [config_file]\n"); - - /* parse program name */ - prog = strrchr(*argv, '/'); - if(prog == (char *)NULL) - prog = *argv; - else - prog++; - argv++; - argc--; - - /* Any options */ - if(argc) - if(argv[0][0] == '-') { - switch (argv[0][1]) { - case 't' : opt_t = 1; - argv++; - argc--; - break; - case 'v' : fprintf(stderr, VERSION"\n"); - exit(EXIT_SUCCESS); - break; - default : fprintf(stderr, VERSION"\n"); - fprintf(stderr, umsg); - exit(EXIT_FAILURE); - } - } - - /* Did they specify an alternate configuration file? */ - if(argc) { - cfg = *argv++; - argc--; - } - - /* Read the configuration settings */ - if(readconfig(cfg, opt_t)) { - fprintf(stderr, "httpd: Error reading configuration file.\n"); - return(-1); - } - - /* Option t is to test configuration only */ - if(opt_t) - return(0); - - /* Open log file for append if it exists */ - if(LogFile != NULL) - if((stdlog = fopen(LogFile, "r")) != (FILE *)NULL) { - fclose(stdlog); - stdlog = fopen(LogFile, "a"); - } - - /* Open debug log file for append if it exists */ - if(DbgFile != NULL) - if((dbglog = fopen(DbgFile, "r")) != (FILE *)NULL) { - fclose(dbglog); - dbglog = fopen(DbgFile, "a"); - } - -#if 0 - /* Get some network information */ - GetNetInfo(); -#endif - - /* If user defined then prepare to secure as user given */ - if(User != NULL) - if((pwd = getpwnam(User)) == (struct passwd *)NULL) { - fprintf(stderr, "httpd: unable to find user %s\n", User); - return(-1); - } - - /* If Chroot defined then secure even more by doing a chroot */ - if(Chroot != NULL) { - if(chroot(Chroot)) { - fprintf(stderr, "httpd: unable to chroot\n"); - return(-1); - } - if(chdir("/")) { - fprintf(stderr, "httpd: unable to chroot\n"); - return(-1); - } - } - - /* If user defined then secure as user given */ - if(User != NULL) - if(setgid(pwd->pw_gid) || setuid(pwd->pw_uid)) { - fprintf(stderr, "httpd: unable to set user\n"); - return(-1); - } - -#if DAEMON - /* Standalone? */ - if (strncmp(prog, "in.", 3) != 0) { - /* Does not start with "in.", so not started from inetd/tcpd. */ - /* XXX - Port name/number should be a config file option. */ - daemonloop("http"); - } -#endif - - /* Get some network information */ - GetNetInfo(); - - /* log a connection */ - if(dbglog != (FILE *)NULL) { - fprintf(dbglog, "CONNECT: %d %s %s\n", getpid(), - rmthostname, logdate((time_t *)NULL)); - fflush(dbglog); - } - - /* loop getting, processing and replying to requests */ - while(!(s = getrequest(&request))) { - if(processrequest(&request, &reply)) break; - if(stdlog != (FILE *)NULL) { - fprintf(stdlog, "%s %s %d %d %s\n", - logdate((time_t *)NULL), rmthostname, - request.method, reply.status, request.url); - fflush(stdlog); - } - if(sendreply(&reply, &request)) break; - if(!reply.keepopen) break; - } - if(s == 1 && stdlog != (FILE *)NULL) { - fprintf(stdlog, "%s %s %d %d %s\n", - logdate((time_t *)NULL), rmthostname, - request.method, 999, request.url); - fflush(stdlog); - } - - return(0); -} diff --git a/commands/httpd/httpd.conf b/commands/httpd/httpd.conf deleted file mode 100644 index d515aae18..000000000 --- a/commands/httpd/httpd.conf +++ /dev/null @@ -1,159 +0,0 @@ -# httpd.conf Sample httpd.conf file By Michael Temari 7/03/2003 - -#serverroot path -# -# path = sets the translation for // -# -# these have special meaning if at beginning of path -# -# /~user = gets replaced with user home directory - -serverroot /~www - -#user username -# -# if present the server will run as the given username otherwise the -# server will run as who ever started it (normally root). - -user www - -#chroot directory -# -# if present the server will be chroot'ed to the given directory name -# normally the home directory of username given above. Be aware if this -# is set then you can only access stuff off this new root. -# -# these have special meaning if at beginning of the directory -# -# // = gets replaced by serverroot directory -# /~user = gets replaced with user home directory - -#chroot /~www - -#logfile filename -# -# the file must exist also and a log of http transactions will be kept -# -# these have special meaning if at the beginning of the filename -# -# // = gets replaced by serverroot directory -# /~user = gets replaced with user home directory - -logfile /usr/adm/httpd.log - -#dbgfile filename -# -# the file must exist also and a debug log of http transactions will be kept -# -# these have special meaning if at the beginning of the filename -# -# // = gets replaced by serverroot directory -# /~user = gets replaced with user home directory - -dbgfile /usr/adm/httpd.dbg - -# dirsend [list of files to try until 1st one is found] -# - -dirsend index.htm - -# direxec [script to run for automatic directory page output] -# -# -# these have special meaning if at beginning of script -# -# // = gets replaced by serverroot directory -# /~user = gets replaced with user home directory -# - -direxec /usr/local/bin/dir2html - -# vhost hostname VhostRoot -# -# vhost is for defining access for virtual hosts. If none are configured then -# any host is accepted. If specified then access is only granted for requests -# for hosts which are configured here. In the Vpath section below the /// gets -# translated to the corresponding VhostRoot. - -# vhost temware.dyndns.org //doc/ -# vhost minix.homeip.net //doc2/ - -# auth authname authdescription access [passwdfile [users]] -# -# auth defines any access authorization to be used in vpath -# -# authname = name to give to this authorization (case insensitive) -# authdescription = Description of this authorization -# access = r=read, w=write, x=execute, h=headers (other than rwxh then no access) -# NOTE: r=file should be read, w=file can be overwrote -# NOTE: x=file should be executed -# NOTE: h=headers (executing program will produce all http headers) -# NOTE: access is on top of unix access -# passwdfile = Name of passwd file to be used (. means /etc/passwd) -# (if none given then no user check) -# users = valid users for this authorization (if none given then all users valid) -# -# these have special meaning if at beginning of passwdfile -# -# // = gets replaced by serverroot directory -# /~user = gets replaced with user home directory -# - -auth AnyBody AnyBody R - System System_User R . - Uploads Uploads RW . root - -# proxyauth authname authdescription access [passwdfile [users]] -# -# proxyauth defines any access authorization to be used for Proxy access -# -# authname = Same as auth above -# authdescription = Same as auth above -# access = Must be R to allow proxy -# passwdfile = Same as auth above -# users = Same as auth above -# - -# proxyauth -# Proxy Proxy R . - - -# vpath from to auth -# -# vpath sets up a list of url path translations and authorizations -# -# from = user specified url -# *=wildcard, $=wildard, but keep path for passing to program -# to = real location -# auth = authname from above (null for no authorization) -# access = r-read, w-write, x-execute (if not given taken from auth record) -# = h-headers (executing program will produce all http headers) -# -# these have special meaning if at beginning of to or serverroot fields -# -# // = gets replaced by serverroot directory -# /// = gets replaced by vhost root directory if configured otherwise same as // -# . = specified authorization only, use other translation elsewhere -# /~user = gets replaced with user home directory -# - -vpath * . AnyBody - /* /// AnyBody - /index.htm . AnyBody X - /ip . AnyBody X - /c1d1$ //exec/cdrom AnyBody X - /c1d2$ //exec/cdrom AnyBody X - /uploads* . Uploads - /src* /usr/src AnyBody R - -# include filename -# -# include tells the server to continue parsing configuration information -# in the given filename -# -# these have special meaning if at beginning of filename -# -# // = gets replaced by serverroot directory -# /~user = gets replaced with user home directory - -include //etc/httpd.mtype diff --git a/commands/httpd/httpd.conf.5 b/commands/httpd/httpd.conf.5 deleted file mode 100644 index ecbc2b4e8..000000000 --- a/commands/httpd/httpd.conf.5 +++ /dev/null @@ -1,328 +0,0 @@ -.TH HTTPD.CONF 5 -.SH NAME -httpd.conf httpd.mtype \- configuration files for the Minix httpd web server -.SH SYNOPSIS -.B /etc/httpd.conf -.B /etc/httpd.mtype -.SH DESCRIPTION -.B /etc/httpd.conf -is the configuration file for the Minix httpd web server written by -Michael Temari. A sample version is included with the distribution -archive and is unpacked in the source directory (normally -.BI /usr/local/src/httpdxxx). -Also provided is an example -.B httpd.mtype -file. This is an extension of the main configuration file which is normally -included when the main file is read. -.P -The makefile does not install -.B httpd.conf -and -.B httpd.mtype -automatically. The sample files included in the distribution are only -examples, you must copy it and edit them for the needs of your own -installation. -.SH CONFIGURATION FILE FORMAT -.B httpd.conf -is an ascii file which consists of lines of the following form: -.P -.B directive LWS [parameters separated by LWS] -.br -NOTE: LWS denotes Linear White Space which is spaces and/or tabs -.SH CONFIGURATION FILE DIRECTIVES -The following are valid configuration file directives (listed in the order -they appear in the sample -.B httpd.conf -file provided in the distribution): -.P -.B serverroot user chroot logfile dbgfile dirsend direxec vhost auth -.B proxyauth vpath include mtype -.P -To make the file more readable, for directives which occupy multiple -lines you may eliminate the directive on lines after the first and begin -these lines with LWS. - -.SH DESCRIPTIONS OF DIRECTIVES -.P -.B serverroot path - -The -.B serverroot -directive sets the translation for -.B // -to the given -.B path. - -.B user username - -The -.B user -directive causes the server to run as the given -.B username -otherwise the server will run as whoever started it (normally root). - -.B chroot directory - -The -.B chroot -directive causes the server to chroot to the given directory after -the configuration and log files have been opened. Normally this will be the -home directory of the given username in the user directive. -.br -NOTE: -.B /~user -will be translated to the home directory of -.B user. -.br -NOTE: -.B // -will be translated to the serverroot directory. -.br -NOTE: if this directive is used then beware of the consequences. - -.B logfile filename - -The -.B logfile -directive tells the server where to log http transactions. -.br -NOTE: the log file must exist to enable logging. - -.B dbgfile filename - -The -.B dbgfile -directive tells the server where to log debugging of http transactions. -.br -NOTE: the debug log file must exist to enable debug logging. - -.B dirsend filelist - -The -.B dirsend -directive tells the server that when a directory is requested -that it should send the first file that it finds in the directory from the -.B filelist -for the request. - -.B direxec program - -The -.B direxec -directive tells the server that when a directory is requested -and no file is found from the -.B dirsend -directive that it should run the given -.B program. -.br -NOTE: the program normally generates a directory listing on the fly using -the -.B dir2html -program. -.br -NOTE: the program access is considered -.B X -with no access restrictions. - -.B vhost hostname vhostroot - -The -.B vhost -directive is for defining access for virtual hosts. If none are configured -then any host is accepted. If specified then access is only granted for -requests for hosts which are configured here. In the -.B vpath -section below the -.B /// -gets translated to the corresponding -.B vhostroot. - - -.B auth authname authdescription access [passwdfile [users]] - -The -.B auth -directive sets up different authorizations with the server. The -.B authname -is the name given to the authorization and is case insensitive. -The -.B authdescription -is the description of the authorization and is what -the user will see when asked to enter a username and password. The -access is one or more of -.B (RWX). -.B R -tells the server the URL can be read. -.B W -tells the server the URL can be overwritten. -.B X -tells the server -that the URL can and should be executed. Access is in addition to normal -Unix security considerations. For instance a file that can be written to -that does not have the -.B W -access will have an error returned. The -.B passwdfile -is the name of the password file to validate users against. If -.B passwdfile -is given as -.B '.' -then the system password file -.B (/etc/passwd) -will be used. If no -.B passwdfile -is given then no authorization is allowed for anyone. If no -.B users -are given then any validated user is authorized, otherwise only the given -.B users -are allowed. - -.B proxyauth authname authdescription access [passwdfile [users]] - -The -.B proxyauth -directive defines access authorization to be used for Proxy access. -.br -.B authname -= Same as auth above -.br -.B authdescription -= Same as auth above -.br -.B access -= Must be R to allow proxy -.br -.B passwdfile -= Same as auth above -.br -.B users -= Same as auth above - -.B vpath from to [auth [access]] - -The -.B vpath -directive sets up URL path translations and authorizations. A -requested URL that matches -.B from -will be translated to -.B to -with the given -.B auth -and -.B access. -If -.B auth -does not exist then the URL will have no -.B access. -If -.B access -is not given then the access is taken from the -.B auth -record (see above). A -.B '.' -in place of the -.B to -means that the server should use a translation from another -.B vpath -record, but associate the given -.B auth -and access with the requested URL. A -.B '*' -may be at the end only of the -.B from -to provide a wildcard match. For example if the -.B from -has -.B /AB* -then any of -.B /ABCDEF -or -.B /AB -or -.B /ABmichael -will match, but -.B /AD or -.B /a -will not. The requested URL is first checked against each -.B vpath -record until an exact match (meaning URL match -.B from -and -.B from -had no -.B '*') -is found or the end of the list. Therefore a wildcard match will match -the last -.B from in the list in which it matched. -.br -NOTE: if at the beginning of the to field -.br - /~user will get translated to the home directory of the given user -.br - // wile get translated to the serverroot directory - -.B include filename - -The -.B include -directive tells the server to read configuration information -from the given filename. -.br -NOTE: normally you get -.B mtype -directives in an included file. - -.B mtype mimetype extensions - -The -.B mtype -directive tells the server what -.B mimetype -to associate with files which have any of the given -.B extensions. -If no match is found then the file will be treated as -.B application/octet-stream. - - -.SH FILES -.B /etc/httpd.conf -.B /etc/httpd.mtype -.B /etc/passwd -.SH "SEE ALSO" -.BR httpd (8) -.BR http_status (5) -.SH NOTES -The source directory contains a commented sample -.B httpd.conf -and -.B httpd.mtype -files -P. -You can run the server as -.B httpd -t /etc/httpd.conf -to see whether the configuration file is being parsed correctly. -.P -Although standard Minix does not have a graphical interface to support -browsers such as Netscape and Microsoft Internet Explorer, the -.B lynx -browser can be used on 32-bit Minix systems with enough memory. You can point -lynx to your own site to browse your own pages. -When debugging a web server there is nothing quite like browsing your own -pages to see whether things are working right. That said, be aware that -different web browsers may vary in how they interpet standard web page -features, and will certainly vary in how they interpret "extensions" to -the HTML standards. So checking a page with several browsers on several -platforms is always a good idea. -.SH BUGS -Not really a bug, but you can get in trouble if a real directory you want -to access shares the first part of its name with a -.B vpath -definition. You just have to pay attention to the directory names you use. -.SH AUTHOR -The Minix httpd server was created by and is maintained by Michael Temari - -.br -This man page was compiled by Al Woodhull -.P -updated 2003-07-06 diff --git a/commands/httpd/httpd.mtype b/commands/httpd/httpd.mtype deleted file mode 100644 index d39335ad1..000000000 --- a/commands/httpd/httpd.mtype +++ /dev/null @@ -1,40 +0,0 @@ -# mime types By Michael Temari 12/29/2002 Ver 0.40 - -# if a file extension is not found in the configuration below the default -# mime type will be application/octet-stream. This default can be changed -# by entering a line with a mime type only with no extension. - -mtype - application/octet-stream - application/compress .Z - application/msword .doc - application/octet-stream .bin .exe - application/pdf .pdf - application/postscript .ps .ai .eps - application/smil .smil - application/x-gtar .gtar - application/x-gzip .gz - application/x-sh .sh - application/x-pn-realaudio .ra .ram - application/x-tar .tar - application/zip .zip - audio/basic .au .snd - audio/mpeg .mp3 - audio/x-aiff .aif .aiff .aifc - audio/x-midi .mid - audio/x-wav .wav - image/bmp .bmp - image/gif .gif - image/jpeg .jpg .jpeg .jpe - image/png .png - image/tiff .tiff .tif - image/x-rgb .rgb - image/x-xbitmap .xbm - multipart/x-www-form-urlencoded .wfu - text/html .html .htm - text/plain .txt .c .h - text/richtext .rtf .rtx - video/mpeg .mpg .mpeg .mpe - video/quicktime .qt .mov - video/x-msvideo .avi - video/x-sgi-movie .movie diff --git a/commands/httpd/httpd0993.txt b/commands/httpd/httpd0993.txt deleted file mode 100644 index bbfac3fd0..000000000 --- a/commands/httpd/httpd0993.txt +++ /dev/null @@ -1,41 +0,0 @@ -httpd0993 --- A www server for Minix 2.0 -written by Michael Temari release 0.993 2003-07-?? - -Httpd is a World Wide Web (WWW) server. I wrote it from scratch so -the setup and configuration will not be like other web servers though -hopefully by reading this document there will be no problems in getting -my web server up and running on your Minix system. - -This is the web server in use on minix1.hampshire.edu and -minix1.bio.umass.edu. - -Installation: unpack the tarball in /usr/local/src or another directory -of your choice: -zcat < httpd0993.tar.Z | tar xvfp - - -An httpd0993 directory will be created and files will be unpacked -there. The README file explains compilation, installation, -configuration, and use. - -Changes for release 0.993: - -- a new method of authorizing proxy. You will no longer need the Proxy -entry in Auth and can remove the http://* entry in vpath. The old way -allowed for having different authorizations depending on what URLs were -asked for via proxy, i.e., you could allow proxy access only to -http:://www.hampshire.edu/. Now it is just a simple authorization for -allowing proxy or not. - -- avoids using a Minix 2.0.3 library call that was not present in Minix -2.0.2, and thus can be compiled with either of the two most recent -Minix releases. - -- a -v option has been added to display the current version then exit. - -- man pages added, other documentation updated. - -Changes for release 0.99: You can set a default in the httpd.mtype -file. A mime type with no extensions on a line will be the default. -Previously recompilation was needed to change the default mime type. - -updated 2003-07-07 \ No newline at end of file diff --git a/commands/httpd/net.c b/commands/httpd/net.c deleted file mode 100644 index 4d2638593..000000000 --- a/commands/httpd/net.c +++ /dev/null @@ -1,240 +0,0 @@ -/* net.c - * - * This file is part of httpd. - * - * 01/25/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "net.h" - -_PROTOTYPE(static void release, (int *fd)); - -ipaddr_t myipaddr, rmtipaddr; -tcpport_t myport, rmtport; -char myhostname[256]; -char rmthostname[256]; -char rmthostaddr[3+1+3+1+3+1+3+1]; - -void GetNetInfo() -{ -nwio_tcpconf_t tcpconf; -int s; -struct hostent *hostent; - - /* Ask the system what our hostname is. */ - if(gethostname(myhostname, sizeof(myhostname)) < 0) - strcpy(myhostname, "unknown"); - - /* lets get our ip address and the clients ip address */ - s = ioctl(0, NWIOGTCPCONF, &tcpconf); - if(s < 0) { - myipaddr = 0; - myport = 0; - rmtipaddr = 0; - rmtport = 0; - strcpy(rmthostname, "??Unknown??"); - strcpy(rmthostaddr, "???.???.???.???"); - return; - } - - myipaddr = tcpconf.nwtc_locaddr; - myport = tcpconf.nwtc_locport; - rmtipaddr = tcpconf.nwtc_remaddr; - rmtport = tcpconf.nwtc_remport; - - /* Look up the host name of the remote host. */ - hostent = gethostbyaddr((char *) &rmtipaddr, sizeof(rmtipaddr), AF_INET); - if(!hostent) - strncpy(rmthostname, inet_ntoa(rmtipaddr), sizeof(rmthostname)-1); - else - strncpy(rmthostname, hostent->h_name, sizeof(rmthostname)-1); - - strcpy(rmthostaddr, inet_ntoa(rmtipaddr)); - - rmthostname[sizeof(rmthostname)-1] = '\0'; - - return; -} - -static void release(fd) -int *fd; -{ - if(*fd != -1) { - close(*fd); - *fd= -1; - } -} - -void daemonloop(service) -char *service; -{ -tcpport_t port; -struct nwio_tcpcl tcplistenopt; -struct nwio_tcpconf tcpconf; -struct nwio_tcpopt tcpopt; -struct servent *servent; -char *tcp_device; -int tcp_fd, client_fd, r; -int pfd[2]; -unsigned stall= 0; - - if((servent= getservbyname(service, "tcp")) == NULL) { - unsigned long p; - char *end; - - p = strtoul(service, &end, 0); - if(p <= 0 || p > 0xFFFF || *end != 0) { - fprintf(stderr, "httpd: %s: Unknown service\n", service); - exit(1); - } - port= htons((tcpport_t) p); - } else - port= servent->s_port; - - /* No client yet. */ - client_fd= -1; - - while (1) { - if((tcp_device = getenv("TCP_DEVICE")) == NULL) - tcp_device = TCP_DEVICE; - if ((tcp_fd= open(tcp_device, O_RDWR)) < 0) { - fprintf(stderr, "httpd: Can't open %s: %s", - tcp_device, strerror(errno)); - if (errno == ENOENT || errno == ENODEV - || errno == ENXIO) { - exit(1); - } - goto bad; - } - - tcpconf.nwtc_flags= NWTC_LP_SET | NWTC_UNSET_RA | NWTC_UNSET_RP; - tcpconf.nwtc_locport= port; - - if (ioctl(tcp_fd, NWIOSTCPCONF, &tcpconf) < 0) { - fprintf(stderr, "httpd: Can't configure TCP channel", - strerror(errno)); - exit(1); - } - -#ifdef NWTO_DEL_RST - tcpopt.nwto_flags= NWTO_DEL_RST; - - if (ioctl(tcp_fd, NWIOSTCPOPT, &tcpopt) < 0) { - fprintf(stderr, "httpd: Can't set TCP options", - strerror(errno)); - exit(1); - } -#endif - - if (client_fd != -1) { - /* We have a client, so start a server for it. */ - -#ifdef NWTO_DEL_RST - tcpopt.nwto_flags= 0; - (void) ioctl(client_fd, NWIOSTCPOPT, &tcpopt); -#endif - - fflush(NULL); - - /* Create a pipe to serve as an error indicator. */ - if (pipe(pfd) < 0) { - fprintf(stderr, "httpd: pipe", strerror(errno)); - goto bad; - } - - /* Fork twice to daemonize child. */ - switch (fork()) { - case -1: - fprintf(stderr, "httpd: fork", strerror(errno)); - close(pfd[0]); - close(pfd[1]); - goto bad; - case 0: - close(tcp_fd); - close(pfd[0]); - switch (fork()) { - case -1: - fprintf(stderr, "httpd: fork", - strerror(errno)); - write(pfd[1], &errno, sizeof(errno)); - exit(1); - case 0: - break; - default: - exit(0); - } - dup2(client_fd, 0); - dup2(client_fd, 1); - close(client_fd); - close(pfd[1]); - - /* Break out of the daemon loop, continuing with - * the normal httpd code to serve the client. - */ - return; - - default: - release(&client_fd); - close(pfd[1]); - wait(NULL); - r= read(pfd[0], &errno, sizeof(errno)); - close(pfd[0]); - if (r != 0) goto bad; - break; - } - } - - /* Wait for a new connection. */ - tcplistenopt.nwtcl_flags= 0; - - while (ioctl(tcp_fd, NWIOTCPLISTEN, &tcplistenopt) < 0) { - if (errno != EAGAIN) { - fprintf(stderr, "httpd: Unable to listen: %s", - strerror(errno)); - } - goto bad; - } - - /* We got a connection. */ - client_fd= tcp_fd; - tcp_fd= -1; - - /* All is well, no need to stall. */ - stall= 0; - continue; - - bad: - /* All is not well, release resources. */ - release(&tcp_fd); - release(&client_fd); - - /* Wait a bit if this happens more than once. */ - if (stall != 0) { - sleep(stall); - stall <<= 1; - } else { - stall= 1; - } - } -} diff --git a/commands/httpd/net.h b/commands/httpd/net.h deleted file mode 100644 index 255fd051b..000000000 --- a/commands/httpd/net.h +++ /dev/null @@ -1,17 +0,0 @@ -/* net.h - * - * This file is part of httpd. - * - * - * 01/25/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ - -_PROTOTYPE(void GetNetInfo, (void)); -_PROTOTYPE(void daemonloop, (char *service)); - -extern char myhostname[256]; -extern char rmthostname[256]; -extern char rmthostaddr[3+1+3+1+3+1+3+1]; diff --git a/commands/httpd/pass.c b/commands/httpd/pass.c deleted file mode 100644 index c7011322e..000000000 --- a/commands/httpd/pass.c +++ /dev/null @@ -1,213 +0,0 @@ -/* pass.c - * - * This file is part of httpd. - * - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef _MINIX -#include -#endif - -#define STD_PASSWD_FILE "/etc/passwd" - -#include "pass.h" - -static char buffer[1024]; -static char *pwduser; -static char *pwdpass; -static char *pwde[4]; - -_PROTOTYPE(static int getuser, (char *pwdfile, char *user)); - -static int getuser(pwdfile, user) -char *pwdfile; -char *user; -{ -FILE *fp; -char *p; -int i; - - if((fp = fopen(pwdfile, "r")) == (FILE *)NULL) - return(-1); - - for(i = 0; i < 4; i ++) pwde[i] = ""; - - while(1) { - if(fgets(buffer, sizeof(buffer), fp) == (char *)NULL) { - fclose(fp); - return(-1); - } - p = buffer; - pwduser = p; - while(*p && *p != ':') p++; - if(*p != ':') continue; - *p++ = '\0'; - if(strcmp(pwduser, user)) continue; - pwdpass = p; - while(*p && *p != ':' && *p != '\r' && *p != '\n') p++; - if(*p == ':') - *p++ = '\0'; - else { - if(*p) *p = '\0'; - fclose(fp); - } - for(i = 0; i < 4; i++) { - pwde[i] = p; - while(*p && *p != ':' && *p != '\r' && *p != '\n') p++; - if(*p == ':') - *p++ = '\0'; - else { - if(*p) *p = '\0'; - break; - } - } - fclose(fp); - - return(0); - } -} - -int passfile(pwdfile) -char *pwdfile; -{ -FILE *fp; - - if(!strcmp(pwdfile, STD_PASSWD_FILE)) - return(0); - - if((fp = fopen(pwdfile, "r")) == (FILE *)NULL) - return(-1); - - fclose(fp); - - return(0); -} - -int passuser(pwdfile, user) -char *pwdfile; -char *user; -{ - if(!strcmp(pwdfile, STD_PASSWD_FILE)) - if(getpwnam(user) == (struct passwd *)NULL) - return(-1); - else - return(0); - - return(getuser(pwdfile, user)); -} - -int passnone(pwdfile, user) -char *pwdfile; -char *user; -{ -struct passwd *pwd; - - if(!strcmp(pwdfile, STD_PASSWD_FILE)) - if((pwd = getpwnam(user)) == (struct passwd *)NULL) - return(-1); - else - if(!strcmp(pwd->pw_passwd, crypt("", pwd->pw_passwd))) - return(-1); - else - return(0); - - if(getuser(pwdfile, user)) - return(-1); - - if(!strcmp(pwdpass, crypt("", pwdpass))) - return(-1); - else - return(0); -} - -int passpass(pwdfile, user, pass) -char *pwdfile; -char *user; -char *pass; -{ -struct passwd *pwd; - - if(!strcmp(pwdfile, STD_PASSWD_FILE)) - if((pwd = getpwnam(user)) == (struct passwd *)NULL) - return(-1); - else - if(strcmp(pwd->pw_passwd, crypt(pass, pwd->pw_passwd))) - return(-1); - else - return(0); - - if(getuser(pwdfile, user)) - return(-1); - - if(strcmp(pwdpass, crypt(pass, pwdpass))) - return(-1); - else - return(0); -} - -int passadd(pwdfile, user, pass, e1, e2, e3, e4) -char *pwdfile; -char *user; -char *pass; -char *e1; -char *e2; -char *e3; -char *e4; -{ -FILE *fp; -time_t salt; -char sl[2]; -int cn; -char *ee1; -char *ee2; -char *ee3; -char *ee4; - - - if(pwdfile == (char *)NULL || - user == (char *)NULL || - pass == (char *)NULL) - return(PASS_ERROR); - - if(!strcmp(pwdfile, STD_PASSWD_FILE)) - return(PASS_ERROR); - - if(!getuser(pwdfile, user)) - return(PASS_USEREXISTS); - - time(&salt); - sl[0] = (salt & 077) + '.'; - sl[1] = ((salt >> 6) & 077) + '.'; - for (cn = 0; cn < 2; cn++) { - if (sl[cn] > '9') sl[cn] += 7; - if (sl[cn] > 'Z') sl[cn] += 6; - } - - if(e1 == (char *)NULL) ee1 = ""; else ee1 = e1; - if(e2 == (char *)NULL) ee2 = ""; else ee2 = e2; - if(e3 == (char *)NULL) ee3 = ""; else ee3 = e3; - if(e4 == (char *)NULL) ee4 = ""; else ee4 = e4; - - /* XXX need to add locking mechanics to add new user */ - - if((fp = fopen(pwdfile, "a")) == (FILE *)NULL) - return(PASS_ERROR); - - fprintf(fp, "%s:%s:%s:%s:%s:%s\n", user, crypt(pass, sl), ee1, ee2, ee3, ee4); - - fclose(fp); - - /* XXX need to add unlocking mechanics to add new user */ - - return(PASS_GOOD); -} diff --git a/commands/httpd/pass.h b/commands/httpd/pass.h deleted file mode 100644 index 22a4e1dc8..000000000 --- a/commands/httpd/pass.h +++ /dev/null @@ -1,18 +0,0 @@ -/* pass.h - * - * This file is part of httpd. - * - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Initial Release Michael Temari - * - */ - -_PROTOTYPE(int passfile, (char *pwdfile)); -_PROTOTYPE(int passuser, (char *pwdfile, char *user)); -_PROTOTYPE(int passnone, (char *pwdfile, char *user)); -_PROTOTYPE(int passpass, (char *pwdfile, char *user, char *pass)); -_PROTOTYPE(int passadd, (char *pwdfile, char *user, char *pass, char *e1, char *e2, char *e3, char *e4)); - -#define PASS_GOOD 0 -#define PASS_USEREXISTS 1 -#define PASS_ERROR -1 diff --git a/commands/httpd/police.c b/commands/httpd/police.c deleted file mode 100644 index b71af8374..000000000 --- a/commands/httpd/police.c +++ /dev/null @@ -1,407 +0,0 @@ -/* police.c - * - * This file is part of httpd. - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "http.h" -#include "utility.h" -#include "config.h" -#include "pass.h" - -#define MATCH_NONE 0 -#define MATCH_WILD 1 -#define MATCH_FULL 2 - -_PROTOTYPE(static int authaccess, (struct http_request *rq, struct http_reply *rp)); -_PROTOTYPE(static void purl, (struct http_request *rq, struct http_reply *rp)); -_PROTOTYPE(static char *virt, (char *to, char *host)); - -static int authaccess(rq, rp) -struct http_request *rq; -struct http_reply *rp; -{ -struct auth *auth; -struct authuser *pu; - - /* set authorization to be checked against */ - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - auth = proxyauth; - else - auth = rp->auth; - - /* no authorization so no access to anyone */ - if(auth == NULL) { - rp->status = HTTP_STATUS_FORBIDDEN; - strcpy(rp->statusmsg, "No Authoriation"); - return(-1); - } - - /* access must be R for PROXY */ - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - if(!(auth->urlaccess & URLA_READ)) { - rp->status = HTTP_STATUS_FORBIDDEN; - strcpy(rp->statusmsg, "Proxy not authorized"); - return(-1); - } - - /* no password file so it is a free for all */ - if(auth->passwdfile == NULL) - return(0); - - /* they did not give us an authorized user */ - if(rq->authuser[0] == '\0') { - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - rp->status = HTTP_STATUS_PROXY_AUTH_REQRD; - else - rp->status = HTTP_STATUS_UNAUTHORIZED; - strcpy(rp->statusmsg, "No Authorized User Given"); - return(-1); - } - - /* check if user okay */ - pu = auth->users; - if(pu == NULL) - ; /* no user list we allow anyone in file */ - else { - while(pu != NULL) { - if(!strcmp(pu->user, rq->authuser)) - break; - pu = pu->next; - } - /* user is not in list so no access */ - if(pu == NULL) { - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - rp->status = HTTP_STATUS_PROXY_AUTH_REQRD; - else - rp->status = HTTP_STATUS_UNAUTHORIZED; - strcpy(rp->statusmsg, "Forbidden User not authorized"); - return(-1); - } - } - - /* check if password file exists, if not no access */ - if(passfile(auth->passwdfile)) { - rp->status = HTTP_STATUS_FORBIDDEN; - strcpy(rp->statusmsg, "Invalid passwd file"); - return(-1); - } - - /* check if user in password file, if not no access */ - if(passuser(auth->passwdfile, rq->authuser)) { - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - rp->status = HTTP_STATUS_PROXY_AUTH_REQRD; - else - rp->status = HTTP_STATUS_UNAUTHORIZED; - strcpy(rp->statusmsg, "Forbidden Bad User"); - return(-1); - } - - /* check if a password exists, if not no access */ - if(passnone(auth->passwdfile, rq->authuser)) { - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - rp->status = HTTP_STATUS_PROXY_AUTH_REQRD; - else - rp->status = HTTP_STATUS_UNAUTHORIZED; - strcpy(rp->statusmsg, "Forbidden no password"); - return(-1); - } - - /* check if password matches, if not no access */ - if(passpass(auth->passwdfile, rq->authuser, rq->authpass)) { - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - rp->status = HTTP_STATUS_PROXY_AUTH_REQRD; - else - rp->status = HTTP_STATUS_UNAUTHORIZED; - strcpy(rp->statusmsg, "Forbidden bad password"); - return(-1); - } - - /* whew, all the checks passed so I guess we let them have it */ - return(0); -} - -int police(rq, rp) -struct http_request *rq; -struct http_reply *rp; -{ -int size; -struct stat st; -struct dirsend *ds; - - purl(rq, rp); - - rp->mtype = "text/html"; - -#ifdef DEBUG - fprintf(stderr, "httpd: Trying %s\n", rp->realurl); -#endif - - /* now check authorizations */ - if(authaccess(rq, rp)) { - /* Don't give them any details why authorization failed */ - strcpy(rp->statusmsg, "No Access Granted"); - return(0); - } - - /* a proxy request only needs an authorization check */ - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - return(0); - - /* check access to real url */ - if(stat(rp->realurl, &st)) { - if(errno == EACCES) - rp->status = HTTP_STATUS_FORBIDDEN; - else - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - /* a PUT and NOT FOUND is okay since we are creating */ - if(rq->method != HTTP_METHOD_PUT || rp->status != HTTP_STATUS_NOT_FOUND) - return(0); - } - - /* If it is a directory do the appropriate thang! */ - if(rq->method == HTTP_METHOD_GET || rq->method == HTTP_METHOD_HEAD) - if((st.st_mode & S_IFMT) == S_IFDIR) { - if(rq->url[strlen(rq->url) - 1] != '/') { - strncat(rq->url, "/", sizeof(rq->url) - strlen(rq->url)); - rp->status = HTTP_STATUS_MOVED_TEMP; - sprintf(rp->statusmsg, "Moved to %s", rq->url); - return(0); - } - size = strlen(rq->url); - ds = dirsend; - while(ds != NULL) { - strncpy(rq->url+size, ds->file, sizeof(rq->url)-size); - purl(rq, rp); - if(stat(rp->realurl, &st)) { - if(errno == EACCES) - rp->status = HTTP_STATUS_FORBIDDEN; - else - if(errno != ENOENT) - rp->status = HTTP_STATUS_NOT_FOUND; - } else - break; - if(rp->status != HTTP_STATUS_OK) { - strcpy(rp->statusmsg, strerror(errno)); - return(0); - } - ds = ds->next; - } - if(ds == NULL) { - rq->url[size] = '\0'; - purl(rq, rp); - if(stat(rp->realurl, &st)) { - if(errno == EACCES) - rp->status = HTTP_STATUS_FORBIDDEN; - else - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - return(0); - } - } - } - - if(rq->method == HTTP_METHOD_PUT && !(rp->urlaccess & URLA_WRITE)) { - rp->status = HTTP_STATUS_METHOD_NOT_ALLOWED; - strcpy(rp->statusmsg, "Method not allowed"); - return(0); - } - - if(rp->status == HTTP_STATUS_OK) { - /* Here is where we check if it is a program or script to run */ - if(cgiexec(rq, rp)) - return(0); - - if((st.st_mode & S_IFMT) == S_IFDIR) { - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, "Directory listing not available"); - return(0); - } - - if((st.st_mode & S_IFMT) != S_IFREG) { - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, "Not a regular file"); - return(0); - } - } - - /* open the URL for updating */ - if(rq->method == HTTP_METHOD_PUT) { - rp->status = HTTP_STATUS_OK; - strcpy(rp->statusmsg, "OK"); - rp->ofd = open(rp->realurl, O_WRONLY | O_CREAT | O_TRUNC); - if(rp->ofd < 0) { - if(errno == EACCES) - rp->status = HTTP_STATUS_FORBIDDEN; - else - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - return(0); - } - return(0); - } - - if(!(rp->urlaccess & URLA_READ)) { - rp->status = HTTP_STATUS_FORBIDDEN; - strcpy(rp->statusmsg, "No way..."); - return(0); - } - - rp->mtype = mimetype(rp->realurl); - - rp->size = st.st_size; - rp->modtime = st.st_mtime; - - /* open the url if it is a file */ - rp->fd = open(rp->realurl, O_RDONLY); - if(rp->fd < 0) { - if(errno == EACCES) - rp->status = HTTP_STATUS_FORBIDDEN; - else - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - return(0); - } - - return(0); -} - -static void purl(rq, rp) -struct http_request *rq; -struct http_reply *rp; -{ -struct vpath *pv; -int gotreal, gotperm; -char *p; -int match; -int len; - - gotreal = 0; gotperm = 0; - -#ifdef DEBUG - fprintf(stderr, "httpd: Processing url = \"%s\"\n", rq->url); -#endif - - /* remove any .. references */ - p = rq->url; - while(*p) { - while(*p && *p != '/') p++; - if(*p != '/') continue; - p++; - if(*p != '.') continue; - p++; - if(*p != '.') continue; - p++; - strcpy(p - 3, p); - p = p - 3; - } - - for(pv = vpath; pv != NULL; pv = pv->next) { - len = strlen(pv->from) - 1; - if(pv->from[len] == '*' || pv->from[len] == '$') - if(len == 0) - match = MATCH_WILD; - else - match = strncmp(rq->url, pv->from, len) ? MATCH_NONE : MATCH_WILD; - else - if(!strcmp(rq->url, pv->from)) - match = MATCH_FULL; - else - match = MATCH_NONE; -#ifdef DEBUG - fprintf(stderr, "httpd: Trying \"%s\" %d %d %d %s\n", - pv->from, match, gotreal, gotperm, pv->auth->name); -#endif - if(match != MATCH_NONE) { - gotperm = 1; - rp->auth = pv->auth; - if(pv->urlaccess == -1 && rp->auth != NULL) - rp->urlaccess = rp->auth->urlaccess; - else - rp->urlaccess = pv->urlaccess; - if(strcmp(pv->to, ".")) { - gotreal = 1; - strncpy(rp->realurl, virt(pv->to, rq->host), sizeof(rp->realurl)); - rp->realurl[sizeof(rp->realurl)-1] = '\0'; - if(match == MATCH_WILD && pv->from[len] != '$') { - strncat(rp->realurl, rq->url+len, sizeof(rp->realurl) - strlen(rp->realurl)); - rp->realurl[sizeof(rp->realurl)-1] = '\0'; - } - } - } - if(match == MATCH_FULL) break; - } - - if(rp->urlaccess == -1) rp->urlaccess = mkurlaccess(""); - - if(!gotreal) { - strncpy(rp->realurl, rq->url, sizeof(rp->realurl)); - rp->realurl[sizeof(rp->realurl)-1] = '\0'; - } - - if(!gotperm) - rp->auth = NULL; - -#ifdef DEBUG - fprintf(stderr, "DEBUG: url = \"%s\" realurl = \"%s\" auth = \"%s\"\n", - rq->url, rp->realurl, ((rp->auth == NULL) ? "No Access" : rp->auth->name)); - fprintf(stderr, "DEBUG: query = %s\n", rq->query); -#endif - - return; -} - -static char *virt(to, host) -char *to; -char *host; -{ -static char vroot[256]; -struct vhost *ph; - -#ifdef DEBUG -fprintf(stderr, "virt: %s %s\n", to, host); -#endif - - if(vhost == NULL) return(to); - - if(to[0] != '/') return(to); - if(to[1] != '/') return(to); - if(to[2] != '/') return(to); - - vroot[0] = '\0'; - - for(ph = vhost; ph != NULL; ph = ph->next) { -#ifdef DEBUG - fprintf(stderr, "ph: %s %s %s\n", ph->hname, ph->root, vroot); -#endif - if(!strcmp(ph->hname, "*") && vroot[0] == '\0') - strncpy(vroot, ph->root, sizeof(vroot)); - if(!strcasecmp(ph->hname, host)) { - strncpy(vroot, ph->root, sizeof(vroot)); - break; - } - } - - strncat(vroot, to+3, sizeof(vroot)); - -#ifdef DEBUG - fprintf(stderr, "vroot: %s\n", vroot); -#endif - - return(vroot); -} diff --git a/commands/httpd/process.c b/commands/httpd/process.c deleted file mode 100644 index 521c3ea91..000000000 --- a/commands/httpd/process.c +++ /dev/null @@ -1,81 +0,0 @@ -/* process.c - * - * This file is part of httpd. - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Relase Michael Temari - * 12/29/2002 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "http.h" -#include "utility.h" - -int processrequest(rq, rp) -struct http_request *rq; -struct http_reply *rp; -{ - /* clear out http_reply */ - memset(rp, 0, sizeof(*rp)); - rp->status = HTTP_STATUS_OK; - strcpy(rp->statusmsg, "OK"); - rp->modtime = (time_t) -1; - rp->urlaccess = -1; - rp->size = 0; - rp->fd = -1; - rp->ofd = -1; - rp->pid = 0; - - /* Simple requests can only be a GET */ - if(rq->type == HTTP_REQUEST_TYPE_SIMPLE && rq->method != HTTP_METHOD_GET) { - rp->status = HTTP_STATUS_BAD_REQUEST; - strcpy(rp->statusmsg, "Bad request"); - return(0); - } - - /* I don't know this method */ - if(rq->method == HTTP_METHOD_UNKNOWN) { - rp->status = HTTP_STATUS_NOT_IMPLEMENTED; - strcpy(rp->statusmsg, "Method not implemented"); - return(0); - } - - /* Check for access and real location of url */ - if(police(rq, rp)) - return(-1); - - /* We're done if there was an error accessing the url */ - if(rp->status != HTTP_STATUS_OK) - return(0); - - /* Check to see if we have a newer version for them */ - if(rq->method == HTTP_METHOD_GET) - if(rq->ifmodsince != (time_t) -1) - if(rq->ifmodsince < time((time_t *)NULL)) - if(rp->modtime != (time_t) -1 && rp->modtime <= rq->ifmodsince) { - rp->status = HTTP_STATUS_NOT_MODIFIED; - strcpy(rp->statusmsg, "Not modified"); - close(rp->fd); - rp->fd = -1; - return(0); - } - - rp->status = HTTP_STATUS_OK; - strcpy(rp->statusmsg, "OK"); - - if(rp->size != 0) - rp->keepopen = rq->keepopen; - - return(0); -} diff --git a/commands/httpd/proxy.c b/commands/httpd/proxy.c deleted file mode 100644 index d93acee9e..000000000 --- a/commands/httpd/proxy.c +++ /dev/null @@ -1,292 +0,0 @@ -/* proxy.c Copyright 2000 by Michael Temari All Rights Reserved */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "http.h" -#include "utility.h" -#include "net.h" - -_PROTOTYPE(static int connect, (char *host)); -#if 0 -_PROTOTYPE(static int readline, (char *p, int len)); -#endif -_PROTOTYPE(static int sendout, (int fd, char *data)); - -static int connect(host) -char *host; -{ -nwio_tcpconf_t tcpconf; -nwio_tcpcl_t tcpcopt; -char *tcp_device; -int netfd; -ipaddr_t nethost; -tcpport_t netport = 0; -struct hostent *hp; -struct servent *sp; -char *p; -int s; -int tries; - - p = host; - while(*p && *p != ':') p++; - if(*p == ':') { - *p++ = '\0'; - netport = htons(atoi(p)); - } - - if((hp = gethostbyname(host)) == (struct hostent *)NULL) { - fprintf(stderr, "Unknown host %s!\n", host); - return(-1); - } else - memcpy((char *) &nethost, (char *) hp->h_addr, hp->h_length); - - /* Now, to which port must we connect? */ - if(netport == 0) - if((sp = getservbyname("http", "tcp")) == (struct servent *)NULL) { - fprintf(stderr, "HTTP port is unknown????\n"); - return(-1); - } else - netport = sp->s_port; - - /* Connect to the host */ - if((tcp_device = getenv("TCP_DEVICE")) == NULL) - tcp_device = TCP_DEVICE; - - if((netfd = open(tcp_device, O_RDWR)) < 0) { - perror("httpget: opening tcp"); - return(-1); - } - - tcpconf.nwtc_flags = NWTC_LP_SEL | NWTC_SET_RA | NWTC_SET_RP; - tcpconf.nwtc_remaddr = nethost; - tcpconf.nwtc_remport = netport; - - s = ioctl(netfd, NWIOSTCPCONF, &tcpconf); - if(s < 0) { - perror("httpget: NWIOSTCPCONF"); - close(netfd); - return(-1); - } - - s = ioctl(netfd, NWIOGTCPCONF, &tcpconf); - if(s < 0) { - perror("httpget: NWIOGTCPCONF"); - close(netfd); - return(-1); - } - - tcpcopt.nwtcl_flags = 0; - - tries = 0; - do { - s = ioctl(netfd, NWIOTCPCONN, &tcpcopt); - if(s == -1 && errno == EAGAIN) { - if(tries++ >= 10) - break; - sleep(10); - } else - break; - } while(1); - - if(s < 0) { - perror("httpget: NWIOTCPCONN"); - close(netfd); - return(-1); - } - - return(netfd); -} - -char buffer[8192]; - -#if 0 -static int readline(p, len) -char *p; -int len; -{ -int c; -int cr = 0; -int n = 0; - - len--; - if(len < 0) return(-1); - while(len > 0 && (c = getchar()) != EOF) { - if(c == '\n' && cr) { - *p = '\0'; - return(n); - } - if(c == '\r') { - cr = 1; - continue; - } - n++; - *p++ = c; - } - *p = '\0'; - return(n); -} -#endif - -static int sendout(fd, data) -int fd; -char *data; -{ - if(strlen(data) > 0) - write(fd, data, strlen(data)); - write(fd, "\r\n", 2); - if(dbglog != (FILE *)NULL) { - fprintf(dbglog, "REPLY: %s\n", data); - fflush(dbglog); - } - - return(0); -} - -void proxy(rq, rp) -struct http_request *rq; -struct http_reply *rp; -{ -int s; -char *p; -char *ps; -char *b; -char *host; -static char user[256]; -static char pass[256]; -char *url; -char *at; -int fd; -int bad; - - while(1) { - bad = 0; - p = rq->uri; - if(tolower(*p++) != 'h') bad++; - if(tolower(*p++) != 't') bad++; - if(tolower(*p++) != 't') bad++; - if(tolower(*p++) != 'p') bad++; - if(tolower(*p++) != ':') bad++; - if(tolower(*p++) != '/') bad++; - if(tolower(*p++) != '/') bad++; - if(bad) { - sprintf(buffer, "HTTP/%d.%d 400 Bad Request", - rq->vmajor, rq->vminor); - sendout(1, buffer); - sendout(1, ""); - sendout(1, "Proxy Request was not http:"); - return; - } - host = p; - while(*p && *p != '/') p++; - url = p; - *url = '\0'; - at = strchr(host, '@'); - if(at != (char *)NULL) { - *at = '\0'; - p = host; - while(*p && *p != ':') p++; - if(*p) - *p++ = '\0'; - strcpy(user, host); - strcpy(pass, p); - host = at + 1; - } else { - user[0] = '\0'; - pass[0] = '\0'; - } - - fd = connect(host); - if(fd < 0) { - sprintf(buffer, "HTTP/%d.%d 400 Bad Request", - rq->vmajor, rq->vminor); - sendout(1, buffer); - sendout(1, ""); - sendout(1, "Could not connect to host"); - return; - } - if(rq->method == HTTP_METHOD_GET) - write(fd, "GET ", 4); else - if(rq->method == HTTP_METHOD_POST) - write(fd, "POST ", 5); - *url = '/'; - if(strlen(url) > 0) - write(fd, url, strlen(url)); - write(fd, " ", 1); - sprintf(buffer, "HTTP/%d.%d", rq->vmajor, rq->vminor); - sendout(fd, buffer); - if(rq->ifmodsince != -1) { - write(fd, "If-Mod-Since: ", 14); - sendout(fd, httpdate(&rq->ifmodsince)); - } - if(rq->size != 0) { - sendout(fd, "Content-Type: application/x-www-form-urlencoded"); - sprintf(buffer, "Content-Length: %lu", rq->size); - sendout(fd, buffer); - } - if(*rq->cookie) { - sprintf(buffer, "Cookie: %s", rq->cookie); - sendout(fd, buffer); - } - if(*rq->useragent) { - sprintf(buffer, "User-Agent: %s", rq->useragent); - sendout(fd, buffer); - } - if(*rq->host) { - sprintf(buffer, "Host: %s", rq->host); - sendout(fd, buffer); - } - if(*rq->wwwauth) { - sprintf(buffer, "Authorization: %s", rq->wwwauth); - sendout(fd, buffer); - } - sprintf(buffer, "X-Forwarded-From: %s", rmthostaddr); - sendout(fd, buffer); - sendout(fd, ""); - if(rq->size != 0) { - if(stdlog != (FILE *)NULL) { - fprintf(stdlog, "%s %s %d %d ", - logdate((time_t *)NULL), rmthostname, - rq->method, rp->status); - fprintf(stdlog, "proxy %s?", rq->uri); - } - while((s = read(0, buffer, rq->size > - sizeof(buffer) ? sizeof(buffer) : rq->size)) > 0) { - write(fd, buffer, s); - rq->size -= s; - b = buffer; - if(stdlog != (FILE *)NULL) - while(s--) fputc(*b++, stdlog); - if(rq->size == 0) break; - } - if(stdlog != (FILE *)NULL) { - fprintf(stdlog, "\n"); - fflush(stdlog); - } - } - while((s = read(fd, buffer, sizeof(buffer))) > 0) { - write(1, buffer, s); - } - close(fd); - return; - } -} diff --git a/commands/httpd/reply.c b/commands/httpd/reply.c deleted file mode 100644 index ba46535b6..000000000 --- a/commands/httpd/reply.c +++ /dev/null @@ -1,189 +0,0 @@ -/* reply.c - * - * This file is part of httpd. - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include - -#include "http.h" -#include "utility.h" -#include "net.h" -#include "config.h" - -#define SERVER "Server: "VERSION - -_PROTOTYPE(static void GotAlarm, (int sig)); -_PROTOTYPE(static int sendout, (char *data)); - -static void GotAlarm(sig) -int sig; -{ -} - -static int sendout(data) -char *data; -{ - if(strlen(data) > 0) - write(1, data, strlen(data)); - write(1, "\r\n", 2); - if(dbglog != (FILE *)NULL) { - fprintf(dbglog, "REPLY: %s\n", data); - fflush(dbglog); - } - - return(0); -} - -int sendreply(rp, rq) -struct http_reply *rp; -struct http_request *rq; -{ -int s; -int s2; -int e; -static char buffer[8192]; - - if(rq->type != HTTP_REQUEST_TYPE_PROXY) - /* We're receiving data from a */ - if(rq->method == HTTP_METHOD_POST || - (rq->method == HTTP_METHOD_PUT && rp->status == HTTP_STATUS_OK)) { - if(rq->type != HTTP_REQUEST_TYPE_FULL) - return(0); - if(rq->method == HTTP_METHOD_PUT) - rp->status = HTTP_STATUS_CREATED; - else - rp->status = HTTP_STATUS_OK; - while(rq->size != 0) { - s = read(0, buffer, (rq->size > sizeof(buffer)) ? sizeof(buffer) : rq->size); - if(s <= 0) { - rp->status = HTTP_STATUS_SERVER_ERROR; - strcpy(rp->statusmsg, strerror(errno)); - close(rp->fd); - close(rp->ofd); - break; - } - rq->size -= s; - s2 = write(rp->ofd, buffer, s); - if(s2 != s) break; - } - } - - if(rp->status != HTTP_STATUS_OK && rp->status != HTTP_STATUS_CREATED && - rp->status != HTTP_STATUS_NOT_MODIFIED) - rp->keepopen = 0; - - if(rp->status == HTTP_STATUS_NOT_MODIFIED) { - sprintf(buffer, "

Error %03d %s

", - rp->status, rp->statusmsg); - rp->size = strlen(buffer); - rp->keepopen = rq->keepopen; - } - - if(!rp->headers) { - - if((rq->type == HTTP_REQUEST_TYPE_PROXY && rp->status != HTTP_STATUS_OK) || - rq->type == HTTP_REQUEST_TYPE_FULL) { - sprintf(buffer, "HTTP/%d.%d %03d %s", - rq->vmajor, rq->vminor, rp->status, rp->statusmsg); - sendout(buffer); - sendout(SERVER); - if(rp->status == HTTP_STATUS_MOVED_PERM || - rp->status == HTTP_STATUS_MOVED_TEMP) { -#if 1 - sprintf(buffer, "Location: %s", rq->url); -#else - sprintf(buffer, "Location: http://%s%s", myhostname, rq->url); -#endif - sendout(buffer); - } - if(rp->keepopen) - sendout("Connection: Keep-Alive"); - else - sendout("Connection: Close"); - if(rp->status == HTTP_STATUS_UNAUTHORIZED && rp->auth != NULL) { - sprintf(buffer, "WWW-Authenticate: Basic realm=\"%s\"", rp->auth->desc); - sendout(buffer); - } - if(rp->status == HTTP_STATUS_PROXY_AUTH_REQRD && proxyauth != NULL) { - sprintf(buffer, "Proxy-Authenticate: Basic realm=\"%s\"", proxyauth->desc); - sendout(buffer); - } - if(rp->modtime != (time_t) -1) { - sprintf(buffer, "Last-Modified: %s", httpdate(&rp->modtime)); - sendout(buffer); - } - if(rp->size != 0) { - sprintf(buffer, "Content-Length: %lu", rp->size); - sendout(buffer); - } - if(rp->status == HTTP_STATUS_OK) { - sprintf(buffer, "Content-Type: %s", rp->mtype); - sendout(buffer); - } else - sendout("Content-Type: text/html"); - if(!rp->headers) - sendout(""); - } else - if(rp->status != HTTP_STATUS_OK) - return(0); - } - - if(rp->status != HTTP_STATUS_OK && rp->status != HTTP_STATUS_CREATED) { - sprintf(buffer, "

Error %03d %s

", - rp->status, rp->statusmsg); - sendout(buffer); - return(0); - } - - if(rq->type == HTTP_REQUEST_TYPE_PROXY) { - proxy(rq, rp); - return(0); - } - - /* send out entity body */ - if(rq->method == HTTP_METHOD_GET || rq->method == HTTP_METHOD_POST) { - errno = 0; - while(1) { - alarm(0); - signal(SIGALRM, GotAlarm); - alarm(10); - s = read(rp->fd, buffer, sizeof(buffer)); - e = errno; - alarm(0); - if(s > 0) { - s2 = write(1, buffer, s); - e = errno; - if(s2 != s) break; - continue; - } - if(s == 0) break; - if(s < 0 && e != EINTR) break; - signal(SIGALRM, GotAlarm); - alarm(2); - s = read(0, buffer, 1); - e = errno; - alarm(0); - if(s < 0 && e != EINTR) break; - } - } - - close(rp->fd); - rp->fd = -1; - if(rp->ofd != -1) - close(rp->ofd); - if(rp->pid != 0 && e != 0) { - kill(-rp->pid, SIGHUP); - rp->pid = 0; - } - - return(0); -} diff --git a/commands/httpd/request.c b/commands/httpd/request.c deleted file mode 100644 index 2b5b36a4f..000000000 --- a/commands/httpd/request.c +++ /dev/null @@ -1,369 +0,0 @@ -/* request.c - * - * This file is part of httpd. - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef _MINIX -#include -#endif -#include - -#include "http.h" -#include "utility.h" -#include "config.h" - -_PROTOTYPE(static void Timeout, (int sig)); -_PROTOTYPE(static int getline, (char *buffer, int size)); -_PROTOTYPE(static void authorize, (char *p, struct http_request *rq)); -_PROTOTYPE(static void decurl, (char *u)); - -static int TimeOut; - -static void Timeout(sig) -int sig; -{ - TimeOut = 1; -} - -static int getline(buffer, size) -char *buffer; -int size; -{ -char *p; -int s; - - p = buffer; - - while(p < (buffer + size - 1)) { - TimeOut = 0; - signal(SIGALRM, Timeout); - alarm(5*60); - s = read(0, p, 1); - alarm(0); - if(TimeOut) - return(-1); - if(s != 1) - return(-1); - if(*p == '\n') break; - p++; - } - *++p = '\0'; - - p = &buffer[strlen(buffer) - 1]; - if(p >= buffer && (*p == '\r' || *p == '\n')) *p-- ='\0'; - if(p >= buffer && (*p == '\r' || *p == '\n')) *p-- ='\0'; - - return(strlen(buffer)); -} - -static void authorize(p, rq) -char *p; -struct http_request *rq; -{ -char *s; - - if(toupper(*p++) == 'B' && - toupper(*p++) == 'A' && - toupper(*p++) == 'S' && - toupper(*p++) == 'I' && - toupper(*p++) == 'C' && - toupper(*p++) == ' ') ; - else - return; - - s = decode64(p); - - if((p = strchr(s, ':')) == (char *)NULL) - p = ""; - else - *p++ = '\0'; - - strncpy(rq->authuser, s, sizeof(rq->authuser)); - strncpy(rq->authpass, p, sizeof(rq->authpass)); - - return; -} - -int getrequest(rq) -struct http_request *rq; -{ -static char line[4096]; -char *p, *p2, *ps; -int s, len; -struct vhost *ph; - - /* get request, it may be simple */ - - s = getline(line, sizeof(line)); - if(s < 0) - return(-1); - - if(dbglog != (FILE *)NULL) { - fprintf(dbglog, "REQUEST: %s\n", line); - fflush(dbglog); - } - - /* clear http_request */ - memset(rq, 0, sizeof(*rq)); - rq->ifmodsince = (time_t) -1; - - /* assume simple request */ - rq->type = HTTP_REQUEST_TYPE_SIMPLE; - - /* parse the method */ - p = line; - while(*p && !LWS(*p)) { - *p = toupper(*p); - p++; - } - if(*p) *p++ = '\0'; - - if(!strcmp(line, "GET")) - rq->method = HTTP_METHOD_GET; else - if(!strcmp(line, "HEAD")) - rq->method = HTTP_METHOD_HEAD; else - if(!strcmp(line, "POST")) - rq->method = HTTP_METHOD_POST; else - if(!strcmp(line, "PUT")) - rq->method = HTTP_METHOD_PUT; else -#if 0 - if(!strcmp(line, "OPTIONS")) - rq->method = HTTP_METHOD_OPTIONS; else - if(!strcmp(line, "PATCH")) - rq->method = HTTP_METHOD_PATCH; else - if(!strcmp(line, "COPY")) - rq->method = HTTP_METHOD_COPY; else - if(!strcmp(line, "MOVE")) - rq->method = HTTP_METHOD_MOVE; else - if(!strcmp(line, "DELETE")) - rq->method = HTTP_METHOD_DELETE; else - if(!strcmp(line, "LINK")) - rq->method = HTTP_METHOD_LINK; else - if(!strcmp(line, "UNLINK")) - rq->method = HTTP_METHOD_UNLINK; else - if(!strcmp(line, "TRACE")) - rq->method = HTTP_METHOD_TRACE; else - if(!strcmp(line, "WRAPPED")) - rq->method = HTTP_METHOD_WRAPPED; else -#endif - rq->method = HTTP_METHOD_UNKNOWN; - - /* parse the requested URI */ - p2 = rq->uri; - len = sizeof(rq->uri) - 1; - while(*p && !LWS(*p) && len > 0) { - *p2++ = *p++; - len--; - } - *p2 = '\0'; - - /* eat up any leftovers if uri was too big */ - while(*p && !LWS(*p)) - p++; - - /* save for continued processing later */ - ps = p; - - /* parse the requested URL */ - p = rq->uri; - p2 = rq->url; - len = sizeof(rq->url) - 1; - while(*p && !LWS(*p) && *p != '?' && len > 0) { - *p2++ = *p++; - len--; - } - *p2 = '\0'; - - /* See if there is a query string */ - if(*p == '?') { - p++; - p2 = rq->query; - len = sizeof(rq->query) - 1; - while(*p && !LWS(*p) && len > 0) { - *p2++ = *p++; - len--; - } - } - - /* eat up any leftovers */ - while(*p && !LWS(*p)) p++; - - if(rq->url[0] == '\0') { - rq->url[0] = '/'; - rq->url[1] = '\0'; - } - - /* url is a decoded copy of the uri */ - decurl(rq->url); - - /* restore and continue processing */ - p = ps; - - /* if this is true it is a simple request */ - if(*p == '\0') - return(0); - - /* parse HTTP version */ - while(*p && LWS(*p)) p++; - if(toupper(*p++) != 'H') return(0); - if(toupper(*p++) != 'T') return(0); - if(toupper(*p++) != 'T') return(0); - if(toupper(*p++) != 'P') return(0); - if( *p++ != '/') return(0); - - /* version major */ - rq->vmajor = 0; - while((*p >= '0') && (*p <= '9')) - rq->vmajor = rq->vmajor * 10 + (*p++ - '0'); - if(*p != '.') - return(0); - p++; - - /* version minor */ - rq->vminor = 0; - while((*p >= '0') && (*p <= '9')) - rq->vminor = rq->vminor * 10 + (*p++ - '0'); - if(*p) - return(0); - - rq->type = HTTP_REQUEST_TYPE_FULL; - - p = rq->uri; - - /* check if it is a proxy request */ - if(toupper(*p++) == 'H' && - toupper(*p++) == 'T' && - toupper(*p++) == 'T' && - toupper(*p++) == 'P' && - toupper(*p++) == ':') - rq->type = HTTP_REQUEST_TYPE_PROXY; - - /* parse any header fields */ - while((s = getline(line, sizeof(line))) > 0) { - if(toupper(line[0]) == 'A' && - toupper(line[1]) == 'U') - if(dbglog != (FILE *)NULL) { - fprintf(dbglog, "REQUEST: Authorization:\n"); - fflush(dbglog); - } else ; - else - if(dbglog != (FILE *)NULL) { - fprintf(dbglog, "REQUEST: %s\n", line); - fflush(dbglog); - } - p = line; - while(*p && *p != ':') { - *p = toupper(*p); - p++; - } - if(*p != ':') continue; /* bad header field, skip it */ - *p++ = '\0'; - while(*p && LWS(*p)) p++; - - /* header field value parsing here */ - if(!strcmp(line, "HOST")) { - strncpy(rq->host, p, sizeof(rq->host)); - p2 = strrchr(rq->host, ':'); - if(p2 != (char *)NULL) { - *p2++ = '\0'; - rq->port = atoi(p2); - } - /* if unknown virtual host then exit quietly */ - for(ph = vhost; ph != NULL; ph = ph->next) { - if(!strcasecmp(ph->hname, "*")) break; - if(!strcasecmp(ph->hname, rq->host)) break; - } - if(rq->type != HTTP_REQUEST_TYPE_PROXY) - if(ph == NULL && vhost != NULL) return(1); - } else - if(!strcmp(line, "USER-AGENT")) - strncpy(rq->useragent, p, sizeof(rq->useragent)); else - if(!strcmp(line, "CONNECTION")) - rq->keepopen = strcasecmp(p, "Keep-Alive") ? 0 : 1; else - if(!strcmp(line, "IF-MODIFIED-SINCE")) - rq->ifmodsince = httptime(p); else - if(!strcmp(line, "CONTENT-LENGTH")) - rq->size = atol(p); else - if(!strcmp(line, "AUTHORIZATION")) { - strncpy(rq->wwwauth, p, sizeof(rq->wwwauth)); - if(rq->type != HTTP_REQUEST_TYPE_PROXY) - authorize(p, rq); - } else - if(!strcmp(line, "PROXY-AUTHORIZATION")) { - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - authorize(p, rq); - } else - if(!strcmp(line, "DATE")) - rq->msgdate = httptime(p); else - if(!strcmp(line, "COOKIE")) { - strncpy(rq->cookie, p, sizeof(rq->cookie)-1); - rq->cookie[sizeof(rq->cookie)-1] = '\0'; - } - } - - if(rq->type != HTTP_REQUEST_TYPE_PROXY) - if(*rq->host == '\0' && vhost != NULL) return(1); - - if(dbglog != (FILE *)NULL && rq->authuser[0] != '\0') { - fprintf(dbglog, "REQUEST: AuthUser=%s\n", rq->authuser); - fflush(dbglog); - } - - if(s < 0) { - fprintf(stderr, "httpd: getrequest: Error getline (header fields)\n"); - return(-1); - } - - return(0); -} - -static void decurl(u) -char *u; -{ -char *p; -char h1, h2; -char c; - - p = u; - while(*p) { - switch(*p) { - case '\0': - c = '\0'; - break; - case '+': - c = ' '; - p++; - break; - case '%': - h1 = '0'; - h2 = '0'; - p++; - h1 = tolower(*p); - if(*p) p++; - h2 = tolower(*p); - if(*p) p++; - c = (h1 > '9') ? (10 + h1 - 'a') : (h1 - '0'); - c = 16 * c + ((h2 > '9') ? (10 + h2 - 'a') : (h2 - '0')); - break; - default: - c = *p++; - } - *u++ = c; - } - *u = '\0'; -} diff --git a/commands/httpd/utility.c b/commands/httpd/utility.c deleted file mode 100644 index 543a9d053..000000000 --- a/commands/httpd/utility.c +++ /dev/null @@ -1,265 +0,0 @@ -/* utility.c - * - * This file is part of httpd - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Initial Release Michael Temari - * - */ -#include -#include -#include -#include -#include -#include - -#include "utility.h" -#include "config.h" - -const char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; -const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - -char *logdate(t) -time_t *t; -{ -time_t worktime; -struct tm *tm; -static char datebuffer[80]; - - if(t == (time_t *)NULL) - (void) time(&worktime); - else - worktime = *t; - - tm = localtime(&worktime); - - sprintf(datebuffer, "%4d%02d%02d%02d%02d%02d", - 1900+tm->tm_year, - tm->tm_mon + 1, - tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - - return(datebuffer); -} - -char *httpdate(t) -time_t *t; -{ -time_t worktime; -struct tm *tm; -static char datebuffer[80]; - - if(t == (time_t *)NULL) - (void) time(&worktime); - else - worktime = *t; - - tm = gmtime(&worktime); - - sprintf(datebuffer, "%s, %02d %s %4d %02d:%02d:%02d GMT", - days[tm->tm_wday], - tm->tm_mday, months[tm->tm_mon], 1900+tm->tm_year, - tm->tm_hour, tm->tm_min, tm->tm_sec); - - return(datebuffer); -} - -time_t httptime(p) -char *p; -{ -time_t worktime, gtime, ltime; -struct tm tm; -struct tm *tm2; -int i; - - worktime = (time_t) -1; - - tm.tm_yday = 0; - tm.tm_isdst = -1; - - /* day of week */ - for(i = 0; i < 7; i++) - if(!strncmp(p, days[i], 3)) break; - if(i < 7) - tm.tm_wday = i; - else - return(worktime); - while(*p && *p != ' ') p++; - if(!*p) return(worktime); - while(*p && *p == ' ') p++; - if(!*p) return(worktime); - - if(*p >= '0' && *p <= '9') { - /* day */ - if(*(p+1) >= '0' && *(p+1) <= '9') - tm.tm_mday = 10 * (*p - '0') + (*(p+1) - '0'); - else - return(worktime); - p += 3; - /* month */ - for(i = 0; i < 12; i++) - if(!strncmp(p, months[i], 3)) break; - if(i < 12) - tm.tm_mon = i; - else - return(worktime); - p += 3; - if(!*p++) return(worktime); - /* year */ - tm.tm_year = atoi(p); - while(*p && *p != ' ') p++; - if(*p) p++; - } else { - /* day */ - tm.tm_mday = atoi(p); - while(*p && *p != ' ') p++; - while(*p && *p == ' ') p++; - if(!*p) return(worktime); - } - - /* hour */ - if(*p < '0' || *p > '9' || *(p+1) < '0' || *(p+1) > '9' || *(p+2) != ':') return(worktime); - tm.tm_hour = 10 * (*p - '0') + (*(p+1) - '0'); - p += 3; - - /* minute */ - if(*p < '0' || *p > '9' || *(p+1) < '0' || *(p+1) > '9' || *(p+2) != ':') return(worktime); - tm.tm_min = 10 * (*p - '0') + (*(p+1) - '0'); - p += 3; - - /* second */ - if(*p < '0' || *p > '9' || *(p+1) < '0' || *(p+1) > '9' || *(p+2) != ' ') return(worktime); - tm.tm_sec = 10 * (*p - '0') + (*(p+1) - '0'); - p += 3; - while(*p && *p == ' ') p++; - if(!*p) return(worktime); - - if(*p >= '0' && *p <= '9') - tm.tm_year = atoi(p); - else - if(*p++ != 'G' || *p++ != 'M' || *p++ != 'T') - return(worktime); - - if(tm.tm_year == 0) - return(worktime); - - if(tm.tm_year > 1900) - tm.tm_year -= 1900; - - worktime = mktime(&tm); - - gtime = mktime(gmtime(&worktime)); - tm2 = localtime(&worktime); - tm2->tm_isdst = 0; - ltime = mktime(tm2); - - worktime = worktime - (gtime - ltime); - - return(worktime); -} - -char *mimetype(url) -char *url; -{ -char *p; -struct msufx *ps; -char *dmt; - - dmt = (char *) NULL; - p = url; - while(*p) { - if(*p != '.') { - p++; - continue; - } - for(ps = msufx; ps != NULL; ps = ps->snext) - if(!strcmp(ps->suffix, "") && dmt == (char *) NULL) - dmt = ps->mtype->mimetype; - else - if(!strcmp(p, ps->suffix)) - return(ps->mtype->mimetype); - p++; - } - - if(dmt == (char *) NULL) - dmt = "application/octet-stream"; - - return(dmt); -} - -char *decode64(p) -char *p; -{ -static char decode[80]; -char c[4]; -int i; -int d; - - i = 0; - d = 0; - - while(*p) { - if(*p >= 'A' && *p <= 'Z') c[i++] = *p++ - 'A'; else - if(*p >= 'a' && *p <= 'z') c[i++] = *p++ - 'a' + 26; else - if(*p >= '0' && *p <= '9') c[i++] = *p++ - '0' + 52; else - if(*p == '+') c[i++] = *p++ - '+' + 62; else - if(*p == '/') c[i++] = *p++ - '/' + 63; else - if(*p == '=') c[i++] = *p++ - '='; else - return(""); - if(i < 4) continue; - decode[d++] = ((c[0] << 2) | (c[1] >> 4)); - decode[d++] = ((c[1] << 4) | (c[2] >> 2)); - decode[d++] = ((c[2] << 6) | c[3]); - decode[d] = '\0'; - i = 0; - } - - return(decode); -} - -int getparms(p, parms, maxparms) -char *p; -char *parms[]; -int maxparms; -{ -int np; - - np = 0; - - if(LWS(*p)) { - while(*p && LWS(*p)) p++; - if(!*p) return(0); - parms[np++] = (char *)NULL; - } else - np = 0; - - while(np < maxparms && *p) { - parms[np++] = p; - while(*p && !LWS(*p)) p++; - if(*p) *p++ = '\0'; - while(*p && LWS(*p)) p++; - } - - return(np); -} - -int mkurlaccess(p) -char *p; -{ -int ua; - - ua = 0; - - while(*p) { - if(toupper(*p) == 'R') ua |= URLA_READ; else - if(toupper(*p) == 'W') ua |= URLA_WRITE; else - if(toupper(*p) == 'X') ua |= URLA_EXEC; else - if(toupper(*p) == 'H') ua |= URLA_HEADERS; else - return(0); - p++; - } - - return(ua); -} diff --git a/commands/httpd/utility.h b/commands/httpd/utility.h deleted file mode 100644 index a66160ead..000000000 --- a/commands/httpd/utility.h +++ /dev/null @@ -1,19 +0,0 @@ -/* utility.h - * - * This file is part of httpd. - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ - -#define LWS(c) ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n')) - -_PROTOTYPE(char *logdate, (time_t *t)); -_PROTOTYPE(char *httpdate, (time_t *t)); -_PROTOTYPE(time_t httptime, (char *p)); -_PROTOTYPE(char *mimetype, (char *url)); -_PROTOTYPE(char *decode64, (char *p)); -_PROTOTYPE(int getparms, (char *p, char *parms[], int maxparms)); -_PROTOTYPE(int mkurlaccess, (char *p)); diff --git a/commands/httpd0995/Makefile b/commands/httpd0995/Makefile deleted file mode 100644 index 19b52c4cb..000000000 --- a/commands/httpd0995/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -# Makefile for httpd -# -# 02/17/1996 Michael Temari -# 07/07/1996 Initial Release Michael Temari -# 12/29/2002 Michael Temari -# 07/07/2003 Al Woodhull -# - -CFLAGS= -O -D_MINIX -D_POSIX_SOURCE -DDAEMON=1 -#CFLAGS= -O -D_MINIX -D_POSIX_SOURCE -DDAEMON=1 -DDEBUG=9 -LDFLAGS=-i -BINDIR=/usr/local/bin - -HTTPD_OBJS= httpd.o utility.o request.o process.o reply.o \ - police.o cgiexec.o net.o config.o pass.o proxy.o -DIR2HTML_OBJS= dir2html.o - -all: httpd dir2html - -httpd: $(HTTPD_OBJS) - $(CC) $(LDFLAGS) -o $@ $(HTTPD_OBJS) - install -S 16kw $@ - -dir2html: $(DIR2HTML_OBJS) - $(CC) $(LDFLAGS) -o $@ $(DIR2HTML_OBJS) - install -S 8kw $@ - -clean: - rm -f httpd $(HTTPD_OBJS) dir2html $(DIR2HTML_OBJS) *.bak - -install: $(BINDIR)/httpd $(BINDIR)/in.httpd $(BINDIR)/dir2html - -tar: - tar cvf ../httpd.tar Makefile README *.c *.h *.sh *.conf *.mtype - -$(BINDIR)/httpd: httpd - install -cs -o bin $? $@ - -$(BINDIR)/in.httpd: $(BINDIR)/httpd - install -l $? $@ - -$(BINDIR)/dir2html: dir2html - install -cs -o bin $? $@ - -httpd.o: httpd.c http.h utility.h net.h config.h -utility.o: utility.c utility.h config.h -request.o: request.c http.h utility.h config.h -process.o: process.c http.h utility.h -reply.o: reply.c http.h utility.h net.h config.h -police.o: police.c http.h utility.h config.h pass.h -cgiexec.o: cgiexec.c http.h config.h -net.o: net.c net.h -config.o: config.c utility.h config.h -pass.o: pass.c pass.h -proxy.o: proxy.c http.h -dir2html.o: dir2html.c - -installman: - mkdir -p /usr/local/man/man5 - mkdir -p /usr/local/man/man8 - cp -p httpd.conf.5 http_status.5 /usr/local/man/man5 - cp -p httpd.8 /usr/local/man/man8 - makewhatis /usr/local/man - - diff --git a/commands/httpd0995/README b/commands/httpd0995/README deleted file mode 100644 index c5574012f..000000000 --- a/commands/httpd0995/README +++ /dev/null @@ -1,252 +0,0 @@ -httpd documentation 7/16/96 by Michael Temari -updated 2006-06-01 by Al Woodhull - -DISCLAIMER: - -Use at own risk etc... - - -COMMENTS: - -Please send me any bug reports, comments, questions, etc... My email -address is Michael@TemWare.Com - - -BACKGROUND: - -httpd is a World Wide Web (WWW) server. I wrote it from scratch so -the setup and configuration will not be like other web servers though -hopefully by reading this document there will be no problems in getting -my web server up and running on your Minix system. - - -COMPILING: - -To compile httpd all you need to do is type "make" in the httpd source -directory. There should be no errors or warnings. If you should run -out of memory when compiling try adding the -m option to the CFLAGS -list in the Makefile. - - -INSTALLING: - -To install httpd all you need to do is type "make install" in the httpd -source directory. By default the place to install httpd is into -/usr/local/bin. If you would like to change this then change BINDIR in -the Makefile. Httpd will be linked to in.httpd, which is the preferred -name for a program started by the tcpd internet access control program. -The program dir2html is also installed -- this provides a directory -listing when a web client accesses a directory which does not contain a -file named index.html (or an alternative designated in /etc/httpd.conf). -The man pages are installed by typing "make installman". - -CONFIGURING: - -Before running httpd it must be configured. The name of the default -configuration file is /etc/httpd.conf or you may pass the configuration -file name to httpd. Upon starting up, httpd will parse the configuration -file and then process requests. This README file and the sample httpd.conf -may also help in configuring. The httpd.conf.5 man page presents the same -information for reference use. - - -The configuration file is an ascii file which consists of lines of the -following form: - -directive LWS [parameters separated by LWS] - -NOTE: LWS denotes Linear White Space which is spaces and/or tabs - -The following are valid configuration file directives: - serverroot redirect user chroot logfile dbgfile dirsend direxec vhost - auth proxyauth vpath include mtype - -To make the file more readable, on directives which occupy multiple -lines you may omit the directive on lines after the first and begin -these lines with LWS. - - -serverroot path - -The serverroot directive sets the translation for // to the given path. - - -redirect url - -If redirect is defined in the configuration file then all request urls -will be redirected. For example, if in the configuration file of -minix1.hampshire.edu this line appears: - redirect http://minix1.woodhull.com/ -a request for http://minix1.hampshire.edu/some/page will return a 301 error -which is a redirect permanent to http://minix1.woodhull.com/some/page. - - -user username - -The user directive causes the server to run as the given username, otherwise -the server will run as whoever started it (normally root). - - -chroot directory - -The chroot directive causes the server to chroot to the given directory after -the configuration and log files have been opened. Normally this will be the -home directory of the given username in the user directive. -NOTE: /~user will be translated to the home directory of the given user - // will be translated to the serverroot directory -NOTE: if this directive is used then beware of the consequences. - - -logfile filename - -The logfile directive tells the server where to log http transactions. -NOTE: the file must exist to enable logging - - -dbgfile filename - -The dbgfile directive tells the server where to log debug http transactions. -NOTE: the file must exist to enable logging - -dirsend filelist - -The dirsend directive tells the server that when a directory is requested -that it should send the first file that it finds in the directory from the -filelist for the request. - - -direxec program - -The direxec directive tells the server that when a directory is requested -and no file is found from the dirsend directive that it should run the -given program. -NOTE: the program normally generates a directory listing on the fly -NOTE: the program access is considered X with no access restrictions. - - -vhost hostname VhostRoot - -vhost is for defining access for virtual hosts. If none are configured then -any host is accepted. If specified then access is only granted for requests -for hosts which are configured here. In the Vpath section below the /// gets -translated to the corresponding VhostRoot. - - -auth authname authdescription access [passwdfile [users]] - -The auth directive sets up different authorizations with the server. The -authname is the name given to the authorization and is case insensitive. -The authdescription is the description of the authorization and is what -the user will see when asked to enter a username and password. The -access is one or more of (rwx). R tells the server the url can be -read. W tells the server the url can be overwritten. X tells the server -that the url can and should be executed. Access is in addition to normal -unix security considerations. For instance a file that can be written to -that does not have the W access will have an error returned. The -passwdfile is the name of the passwdfile to validate users against. If -the passwdfile is given as '.' then the system password file will be used -which is /etc/passwd. If no passwdfile is given then no authorization is -allowed for anyone. If no users are given then any validated users is -authorized, otherwise only the given users are allowed. - - -proxyauth authname authdescription access [passwdfile [users]] - -proxyauth defines any access authorization to be used for Proxy access -authname = Same as auth above -authdescription = Same as auth above -access = Must be R to allow proxy -passwdfile = Same as auth above -users = Same as auth above - - -vpath from to [auth [access]] - -The vpath directive sets up url path translations and authorizations. A -requested url that matches from will be translated to to with the given -auth and access. If auth does not exist then the url will have no access. -If access is not given then the access is taken from the auth record (see -above). A '.' in place of the to means that the server should use a -translation from another vpath record, but associate the given auth and -access with the requested url. A '*' maybe at the end only of the from -which is a wildcard match. For example if the from has /AB* then any of -/ABCDEF or /AB or /ABmichael will match, but /AD or /a will not. The -requested url is first checked against each vpath record until an exact -match (meaning url match from and from had no '*') is found or the end of -the list. Therefore a wildcard match will match the last from is the list -in which it matched. -NOTE: if at the beginning of the to field - /~user will get translated to the home directory of the given user - // wile get translated to the serverroot directory - - -include filename - -The include directive tells the server to read configuration information -from the given filename. -NOTE: normally mtype directives are included from another file - - -mtype mimetype extensions - -The mtype directive tells the server what mimetype to associate with files -which have any of the given extensions. If no match is found then the file -will be treated as application/octet-stream. -NOTE: normally you get mtype directives in included file - - - -USAGE: - - httpd [-v|-t] [configuration-file] - -The -t tells the server to just parse the configuration file so that you -can test it to see if it is the way you want it. You may also pass the -name of your configuration file if it is not the default /etc/httpd.conf. - -The -v option prints the server version and then exits. - - -STARTING: - -First of all httpd is a server and therefore you will need to start it -with tcpd. Tcpd is a program which listens for incoming TCP connections -on the passed port and when a connection comes in it forks and starts the -given daemon program. Therefore to start httpd you use: - - tcpd http /usr/local/bin/in.httpd & - -You will more than likely have this line in your /etc/rc or /etc/rc.net -file so that whenever your system is restarted the web server will also -be started. The first parameter http is the port that tcpd is going -to be listening for connections on. Here http (which should be defined -in /etc/services as 80) is the standard port for a web server. The second -parameter is the program that tcpd will fork and exec when a connection -comes in. The program will then have its stdin and stderr connected to -the client Then the web server program will start running with the tcpd -program waiting for the next connection. Currently there is no ability to -limit the number of simultaneous web servers running. NOTE: At some point -I will be adding the ability for httpd to start itself without the need of -tcpd. That way httpd will already be in memory and have parsed its -configuration file. - -In Minix 2.0.3 and later versions you may use: - - daemonize tcpd http /usr/local/bin/in.httpd - -(daemonize is a shell function defined in /usr/etc/rc which starts programs -as daemons). - - -FINAL WORDS - -I wanted to get the server out as soon as possible so I hurried up and -created this document to help out. Hopefully it will HELP more than -it HURTS. If anyone is interested in writing man pages for httpd or any -of the other network programs please let me know. - - -Michael Temari -Michael@TemWare.Com - -Please note also the SECURITY document in this directory. (asw 2003-07-05) diff --git a/commands/httpd0995/SECURITY b/commands/httpd0995/SECURITY deleted file mode 100644 index 88c73056c..000000000 --- a/commands/httpd0995/SECURITY +++ /dev/null @@ -1,52 +0,0 @@ -SECURITY NOTE - -Al Woodhull updated 2006-06-01 - -Running a web server is fun, but it's also not without risks. If, like -many Minix users, you are a guest on someone else's network, you need -to be very careful to operate your server in ways that will not put -your system at risk or interfere with others on the net. Here are some -points to consider: - -- Be sure to touch /usr/adm/httpd.log (or whatever you specify as the log -file in httpd.conf) before you start your web server for the first time --- nothing will be logged if the log file does not exist. Then look at -your log file frequently and be alert for any unusual activity. - -- You may also want to be sure that you have provided a /etc/serv.access -file. This file can be used to limit access only to permitted nodes or -networks, or to deny access to specified nodes or networks (see the -serv.access (5) man page). Also, even if your /etc/serv.access file is -empty, if it is present tcpd will exec its paranoid twin tcpdp, which -will refuse service if the connecting IP address cannot be associated -with a name. - -- If you enable proxy webserving, be very careful, it can be used by -people you don't know to visit sites that don't welcome visitors whose -identity is hidden. This may cause your network host and ultimately you -some unpleasantness. - -- The Minix httpd can also support CGI applications. These are also -dangerous -- a CGI application allows someone else to execute a program -on your computer. Make sure anything you allow this way cannot be -abused. Many security violations are due to effects of input that was not -expected by the original author of a program. - -- It's an understatement to say that Minix is not a well-known -operating system. There are not many Minix systems operating as -servers on the internet. A consequence of this is that there few, if -any, people engaged in finding ways to attack weaknesses in Minix. But -the idea of "security through obscurity" is deprecated by serious -computer security experts. Any operating system or program of any -degree of complexity is likely to have bugs or features that can be -exploited in ways the original programmers did not foresee. You can't -count on the "good guys" being the first ones to discover a risk. -There are two things you should be sure to do if you are running a -network server of any kind: - -(1) be alert for new versions of the program that may fix bugs -discovered by other users, and - -(2) be sure to report to the program author or maintainer anything you -observe that looks like a bug or a way the program can be misused. - diff --git a/commands/httpd0995/cgiexec.c b/commands/httpd0995/cgiexec.c deleted file mode 100644 index 856a51200..000000000 --- a/commands/httpd0995/cgiexec.c +++ /dev/null @@ -1,255 +0,0 @@ -/* cgiexec.c by Michael Temari 02/17/96 - * - * This file is part of httpd. - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * 02/08/2005 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "http.h" -#include "config.h" -#include "net.h" - -_PROTOTYPE(char **cgienv, (struct http_request *rq, struct http_reply *rp)); -_PROTOTYPE(static int addenv, (char *name, char *value, char **buf, int *len)); - -int cgiexec(rq, rp) -struct http_request *rq; -struct http_reply *rp; -{ -struct stat st; -char *prog; -int cmdpid; -int status; -char *argv[5]; -int ifds[2]; -int ofds[2]; -static char cmd[2048]; -char **cmdenv; -int dirflag = 0; - - if(stat(rp->realurl, &st)) { - if(errno == EACCES) - rp->status = HTTP_STATUS_FORBIDDEN; - else - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - return(-1); - } - - if((st.st_mode & S_IFMT) == S_IFDIR) - if(direxec != NULL) { - prog = direxec; dirflag = 1; - } else - return(0); - else - prog = rp->realurl; - - /* check if prog is allowed to be exec'd */ - if(!dirflag && !(rp->urlaccess & URLA_EXEC)) - return(0); - - /* if cannot exec mode then return */ - if( (st.st_mode & S_IXUSR) == 0 && - (st.st_mode & S_IXGRP) == 0 && - (st.st_mode & S_IXOTH) == 0 ) - return(0); - - if((cmdenv = cgienv(rq, rp)) == NULL) { - rp->status = HTTP_STATUS_SERVER_ERROR; - strcpy(rp->statusmsg, "Could not setup cgi environment"); - return(-1); - } - - argv[0] = prog; - argv[1] = rp->realurl; - argv[2] = rq->url; - argv[3] = (char *)NULL; - - if(pipe(ifds) < 0) { - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - return(-1); - } - - if(pipe(ofds) < 0) { - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - close(ifds[0]); close(ifds[1]); - return(-1); - } - - if((cmdpid = fork()) < 0) { - close(ifds[0]); close(ofds[0]); - close(ifds[1]); close(ofds[1]); - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - return(-1); - } - - /* We don't know how much data is going to be passed back */ - rp->size = 0; - - if(cmdpid == 0) { /* Child */ -#if 0 - if((cmdpid = fork()) < 0) { - close(ifds[0]); close(ofds[0]); - close(ifds[1]); close(ofds[1]); - exit(-1); - } - if(cmdpid != 0) { - close(ifds[0]); close(ofds[0]); - close(ifds[1]); close(ofds[1]); - exit(0); - } -#endif - setsid(); - close(ifds[0]); close(ofds[1]); - dup2(ofds[0], 0); - dup2(ifds[1], 1); - dup2(ifds[1], 2); - close(ifds[1]); close(ofds[0]); - execve(argv[0], argv, cmdenv); - exit(0); - } - -#if 0 - /* Get rid of Zombie child */ - (void) wait(&status); -#endif - - close(ifds[1]); close(ofds[0]); - - rp->fd = ifds[0]; - rp->ofd = ofds[1]; - rp->pid = cmdpid; - - if(rp->urlaccess & URLA_HEADERS) - rp->headers = -1; - - return(-1); -} - -char **cgienv(rq, rp) -struct http_request *rq; -struct http_reply *rp; -{ -static char buffer[4096]; -char *p, *p2; -char **e; -int len; -char temp[20]; - - p = buffer; - len = sizeof(buffer); - - if(addenv("PATH", "/usr/local/bin:/bin:/usr/bin", &p, &len)) return(NULL); - if(getenv("TZ") != (char *)NULL) - if(addenv("TZ", getenv("TZ"), &p, &len)) return(NULL); - - /* HACK - some of these are hardcoded and should not be MAT 3/17/96 */ - - /* HTTP_ */ - - if(addenv("SERVER_SOFTWARE", "Temari httpd/1.0", &p, &len)) return(NULL); - if(addenv("SERVER_NAME", myhostname, &p, &len)) return(NULL); - if(addenv("GATEWAY_INTERFACE", "CGI/1.1", &p, &len)) return(NULL); - if(addenv("SERVER_PROTOCOL", "HTTP/1.0", &p, &len)) return(NULL); - if(rq->port) - sprintf(temp, "%u", rq->port); - else - strcpy(temp, "80"); - if(addenv("SERVER_PORT", temp, &p, &len)) return(NULL); - switch(rq->method) { - case HTTP_METHOD_GET: - if(addenv("REQUEST_METHOD", "GET", &p, &len)) return(NULL); - break; - case HTTP_METHOD_POST: - if(addenv("REQUEST_METHOD", "POST", &p, &len)) return(NULL); - break; - case HTTP_METHOD_HEAD: - if(addenv("REQUEST_METHOD", "HEAD", &p, &len)) return(NULL); - break; - case HTTP_METHOD_PUT: - if(addenv("REQUEST_METHOD", "PUT", &p, &len)) return(NULL); - break; - default: - if(addenv("REQUEST_METHOD", "UNKNOWN", &p, &len)) return(NULL); - } - if(addenv("PATH_INFO", "?", &p, &len)) return(NULL); - if(addenv("PATH_TRANSLATED", "?", &p, &len)) return(NULL); - if(addenv("SCRIPT_NAME", rq->url, &p, &len)) return(NULL); - if(addenv("QUERY_STRING", rq->query, &p, &len)) return(NULL); - if(addenv("REMOTE_HOST", rmthostname, &p, &len)) return(NULL); - if(addenv("REMOTE_ADDR", rmthostaddr, &p, &len)) return(NULL); - if(rq->authuser != (char *)NULL) - if(addenv("AUTH_USER", rq->authuser, &p, &len)) return(NULL); - /* AUTH_TYPE */ - /* REMOTE_USER */ - /* REMOTE_IDENT */ - if(rq->method == HTTP_METHOD_POST) { - if(addenv("CONTENT_TYPE", "application/x-www-form-urlencoded", &p, &len)) return(NULL); - sprintf(temp, "%lu", rq->size); - if(addenv("CONTENT_LENGTH", temp, &p, &len)) return(NULL); - } - /* COOKIE */ - if(rq->cookie[0] != '\0') - if(addenv("COOKIE", rq->cookie, &p, &len)) return(NULL); - /* HOST */ - if(addenv("HOST", rq->host, &p, &len)) return(NULL); - - if(len < 1) return(NULL); - *p++ = '\0'; - - p2 = buffer; - e = (char **)p; - while(*p2) { - if(len < sizeof(e)) return(NULL); - len -= sizeof(e); - *e++ = p2; - while(*p2) p2++; - p2++; - } - if(len < sizeof(e)) return(NULL); - *e++ = NULL; - - return((char **)p); -} - -static int addenv(name, value, buf, len) -char *name; -char *value; -char **buf; -int *len; -{ -char *p; -int size; - - p = *buf; - - size = strlen(name)+1+strlen(value)+1; - - if(size > *len) - return(-1); - - sprintf(p, "%s=%s", name, value); - - p += size; - *buf = p; - *len -= size; - - return(0); -} diff --git a/commands/httpd0995/config.c b/commands/httpd0995/config.c deleted file mode 100644 index 4c818745a..000000000 --- a/commands/httpd0995/config.c +++ /dev/null @@ -1,841 +0,0 @@ -/* config.c by Michael Temari 02/26/96 - * - * This file is part of httpd. - * - * 02/26/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * 05/14/2006 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include - -#include "utility.h" -#include "config.h" - -struct mtype *mtype = NULL; -struct msufx *msufx = NULL; -struct vhost *vhost = NULL; -struct vpath *vpath = NULL; -struct dirsend *dirsend = NULL; -struct auth *auth = NULL; -struct auth *proxyauth = NULL; -char *direxec = NULL; -char *srvrroot = ""; -char *Redirect = NULL; -char *LogFile = NULL; -char *DbgFile = NULL; -char *User = NULL; -char *Chroot = NULL; - -_PROTOTYPE(static int doconfig, (char *cfg_file)); -_PROTOTYPE(static int doinclude, (char *parms[], int np)); -_PROTOTYPE(static int domtype, (char *parms[], int np)); -_PROTOTYPE(static struct auth *findauth, (char *name)); -_PROTOTYPE(static int dovhost, (char *parms[], int np)); -_PROTOTYPE(static int dovpath, (char *parms[], int np)); -_PROTOTYPE(static int dosrvrroot, (char *parms[], int np)); -_PROTOTYPE(static int doredirect, (char *parms[], int np)); -_PROTOTYPE(static int dodirsend, (char *parms[], int np)); -_PROTOTYPE(static int dodirexec, (char *parms[], int np)); -_PROTOTYPE(static char *subvpath, (char *s)); -_PROTOTYPE(static int dologfile, (char *parms[], int np)); -_PROTOTYPE(static int dodbgfile, (char *parms[], int np)); -_PROTOTYPE(static int douser, (char *parms[], int np)); -_PROTOTYPE(static int dochroot, (char *parms[], int np)); -_PROTOTYPE(static int adduser, (struct auth *pauth, char *user)); -_PROTOTYPE(static int doauth, (char *parms[], int np)); -_PROTOTYPE(static int doproxyauth, (char *parms[], int np)); - -int readconfig(cfg_file, testing) -char *cfg_file; -int testing; -{ -int s; -char *cfg; -struct msufx *ps; -struct mtype *pt; -struct vhost *ph; -struct vpath *pv; -struct dirsend *pd; -struct auth *pa; - - cfg = HTTPD_CONFIG_FILE; - if(cfg_file != (char *)NULL) - if(*cfg_file) - cfg = cfg_file; - - s = doconfig(cfg); - - if(testing) { - printf("ServerRoot: %s\n", srvrroot); - printf("Redirect: %s\n", Redirect == NULL ? "" : Redirect); - printf("UserName: %s\n", User == NULL ? "" : User); - printf("Chroot: %s\n", Chroot == NULL ? "" : Chroot); - printf("LogFile: %s\n", LogFile == NULL ? "" : LogFile); - printf("DbgFile: %s\n", DbgFile == NULL ? "" : DbgFile); - printf("DirSend:"); - for(pd = dirsend; pd != NULL; pd = pd->next) - printf(" %s", pd->file); - printf("\n"); - printf("DirExec: %s\n", direxec == NULL ? "" : direxec); - for(ph = vhost; ph != NULL; ph = ph->next) - printf("VHost: %s %s\n", ph->hname, ph->root); - for(pa = auth; pa != NULL; pa = pa->next) - printf("Auth: %s %s %d %s\n", - pa->name, pa->desc, pa->urlaccess, pa->passwdfile); - for(pa = proxyauth; pa != NULL; pa = pa->next) - printf("ProxyAuth: %s %s %d %s\n", - pa->name, pa->desc, pa->urlaccess, pa->passwdfile); - for(pv = vpath; pv != NULL; pv = pv->next) - printf("Vpath: %s %s %s %d\n", - pv->from, pv->to, pv->auth->name, pv->urlaccess); - for(pt = mtype; pt != NULL; pt = pt->next) { - printf("MType: %s :", pt->mimetype); - for(ps = pt->msufx; ps != NULL; ps = ps->tnext) - printf(" '%s'", ps->suffix); - printf("\n"); - } - for(ps = msufx; ps != NULL; ps = ps->snext) - printf("Suffix: %s\t%s\n", ps->suffix, ps->mtype->mimetype); - } - - return(s); -} - -static int doconfig(cfg_file) -char *cfg_file; -{ -FILE *fp; -int np; -int s; -char *p; -char ltype[40]; -char *parms[30]; -static char buffer[2048]; - - if((fp = fopen(cfg_file, "r")) == (FILE *)NULL) { - fprintf(stderr, "httpd: Could not read %s config file.\n", cfg_file); - return(-1); - } - - *ltype = '\0'; - - while(fgets(buffer, sizeof(buffer), fp) != (char *)NULL) { - if(buffer[0] == '#') continue; /* skip comments */ - np = getparms(buffer, parms, sizeof(parms)/sizeof(parms[0])); - if(np == 0) continue; /* blank line */ - if(parms[0] == (char *)NULL) - parms[0] = ltype; - else { - p = parms[0]; - while(*p) *p++ = tolower(*p); - strncpy(ltype, parms[0], sizeof(ltype)); - } - s = 0; - if(!strcmp(parms[0], "mtype")) s = domtype(parms, np); - else - if(!strcmp(parms[0], "vhost")) s = dovhost(parms, np); - else - if(!strcmp(parms[0], "vpath")) s = dovpath(parms, np); - else - if(!strcmp(parms[0], "serverroot")) s = dosrvrroot(parms, np); - else - if(!strcmp(parms[0], "redirect")) s = doredirect(parms, np); - else - if(!strcmp(parms[0], "dirsend")) s = dodirsend(parms, np); - else - if(!strcmp(parms[0], "direxec")) s = dodirexec(parms, np); - else - if(!strcmp(parms[0], "logfile")) s = dologfile(parms, np); - else - if(!strcmp(parms[0], "dbgfile")) s = dodbgfile(parms, np); - else - if(!strcmp(parms[0], "user")) s = douser(parms, np); - else - if(!strcmp(parms[0], "chroot")) s = dochroot(parms, np); - else - if(!strcmp(parms[0], "auth")) s = doauth(parms, np); - else - if(!strcmp(parms[0], "proxyauth")) s = doproxyauth(parms, np); - else - if(!strcmp(parms[0], "include")) s = doinclude(parms, np); - else - fprintf(stderr, "httpd: Unknown directive: %s\n", parms[0]); - if(s) { - fprintf(stderr, "httpd: Error processing config file\n"); - fclose(fp); - return(-1); - } - } - - fclose(fp); - - return(0); -} - -static int doinclude(parms, np) -char *parms[]; -int np; -{ -char *p; - - if(np < 2) return(0); - - p = subvpath(parms[1]); - - return(doconfig(p)); -} - -static int domtype(parms, np) -char *parms[]; -int np; -{ -int i; -struct mtype *pt, *lpt, *newpt; -struct msufx *ps, *lps, *newps, *psend; - - if(np < 2) return(0); - - - /* check if this mime type already exists in the list */ - for(pt = mtype, lpt = NULL; pt != NULL; lpt = pt, pt = pt->next) - if(!strcmp(parms[1], pt->mimetype)) - break; - - if(pt == NULL) { /* not there so add it */ - newpt = malloc(sizeof(struct mtype)); - if(newpt == NULL) { - fprintf(stderr, "httpd: malloc failed in domtype\n"); - return(-1); - } - newpt->mimetype = malloc(strlen(parms[1])+1); - if(newpt->mimetype == NULL) { - fprintf(stderr, "httpd: malloc failed in domtype\n"); - return(-1); - } - strcpy(newpt->mimetype, parms[1]); - newpt->msufx = NULL; - newpt->next = NULL; - if(lpt == NULL) - mtype = newpt; - else - lpt->next = newpt; - } else - newpt = pt; - - /* find end of suffix list */ - for(ps = newpt->msufx, lps = NULL; ps != NULL; lps = ps, ps = ps->tnext) ; - psend = lps; - - /* if no suffix given then add empty suffix for default */ - if(np == 2) - strcpy(parms[np++], ""); - - /* add each suffix to the mime type */ - for(i = 2; i < np; i++) { - /* a suffix can only be for a single mime type */ - for(ps = msufx, lps = NULL; ps != NULL; lps = ps, ps = ps->snext) { - if(!strcmp(ps->suffix, parms[i])) { - fprintf(stderr, "httpd: Suffix already found\n"); - return(-1); - } - if(strlen(parms[i]) > strlen(ps->suffix)) break; - } - newps = malloc(sizeof(struct msufx)); - if(newps == NULL) { - fprintf(stderr, "httpd: malloc failed in domtype\n"); - return(-1); - } - newps->suffix = malloc(strlen(parms[i])+1); - if(newps->suffix == NULL) { - fprintf(stderr, "httpd: malloc failed in domtype\n"); - return(-1); - } - strcpy(newps->suffix, parms[i]); - newps->mtype = newpt; - newps->snext = NULL; - newps->tnext = NULL; - if(lps == NULL) { - msufx = newps; - newps->snext = ps; - } else { - lps->snext = newps; - newps->snext = ps; - } - if(psend == NULL) - newpt->msufx = newps; - else - psend->tnext = newps; - psend = newps; - } - - return(0); -} - -static struct auth *findauth(name) -char *name; -{ -char lname[80]; -char *p, *p2; -struct auth *a = NULL; - - if(sizeof(lname) < (strlen(name)+1)) { - fprintf(stderr, "httpd: lname too small in findauth\n"); - return(a); - } - p = name; p2 = lname; - while(*p) - *p2++ = tolower(*p++); - *p2 = '\0'; - - for(a = auth; a != NULL; a = a->next) - if(!strcmp(a->name, lname)) break; - - return(a); -} - -static int dovhost(parms, np) -char *parms[]; -int np; -{ -char *hname, *root; -struct vhost *ph, *lph, *newph; - - if(np < 2) return(0); - - hname = parms[1]; - - if(np < 3) - root = ""; - else - root = parms[2]; - - for(ph = vhost, lph = NULL; ph != NULL; lph = ph, ph = ph->next) - ; - - newph = malloc(sizeof(struct vhost)); - if(newph == NULL) { - fprintf(stderr, "httpd: malloc failed in dovhost\n"); - return(-1); - } - newph->hname = malloc(strlen(hname)+1); - if(newph->hname == NULL) { - fprintf(stderr, "httpd: malloc failed in dovhost\n"); - return(-1); - } - strcpy(newph->hname, hname); - - root = subvpath(root); - - newph->root = malloc(strlen(root)+1); - if(newph->root == NULL) { - fprintf(stderr, "httpd: malloc failed in dovhost\n"); - return(-1); - } - strcpy(newph->root, root); - - if(np > 3) - if(parms[3][0] != '#') { - fprintf(stderr, "httpd: junk at end of vhost line\n"); - return(-1); - } - - newph->next = NULL; - if(lph == NULL) { - vhost = newph; - newph->next = ph; - } else { - lph->next = newph; - newph->next = ph; - } - - return(0); -} - -static int dovpath(parms, np) -char *parms[]; -int np; -{ -char *from, *to; -struct vpath *pv, *lpv, *newpv; - - if(np < 3) return(0); - - from = parms[1]; - to = parms[2]; - - for(pv = vpath, lpv = NULL; pv != NULL; lpv = pv, pv = pv->next) - ; - - newpv = malloc(sizeof(struct vpath)); - if(newpv == NULL) { - fprintf(stderr, "httpd: malloc failed in dovpath\n"); - return(-1); - } - newpv->from = malloc(strlen(from)+1); - if(newpv->from == NULL) { - fprintf(stderr, "httpd: malloc failed in dovpath\n"); - return(-1); - } - strcpy(newpv->from, from); - - to = subvpath(to); - - newpv->to = malloc(strlen(to)+1); - if(newpv->to == NULL) { - fprintf(stderr, "httpd: malloc failed in dovpath\n"); - return(-1); - } - strcpy(newpv->to, to); - - newpv->auth = NULL; - newpv->urlaccess = -1; - - if(np > 3) - if(parms[3][0] != '#') { - newpv->auth = findauth(parms[3]); - if(np > 4) - if(parms[4][0] != '#') { - newpv->urlaccess = mkurlaccess(parms[4]); - if(np > 5) - if(parms[5][0] != '#') { - fprintf(stderr, "httpd: junk at end of vpath line\n"); - return(-1); - } - } - } - - newpv->next = NULL; - if(lpv == NULL) { - vpath = newpv; - newpv->next = pv; - } else { - lpv->next = newpv; - newpv->next = pv; - } - - return(0); -} - -static int dosrvrroot(parms, np) -char *parms[]; -int np; -{ -char *newroot; - - if(np < 2) return(0); - - newroot = subvpath(parms[1]); - - srvrroot = malloc(strlen(newroot)+1); - if(srvrroot == NULL) { - fprintf(stderr, "httpd: malloc failed in dosrvrroot\n"); - return(-1); - } - strcpy(srvrroot, newroot); - if(srvrroot[strlen(srvrroot)-1] == '/') - srvrroot[strlen(srvrroot)-1] = '\0'; - - return(0); -} - -static int doredirect(parms, np) -char *parms[]; -int np; -{ -char *redir; - - if(np < 2) return(0); - - redir = subvpath(parms[1]); - - Redirect = malloc(strlen(redir)+1); - if(Redirect == NULL) { - fprintf(stderr, "httpd: malloc failed in doredirect\n"); - return(-1); - } - strcpy(Redirect, redir); - if(Redirect[strlen(Redirect)-1] == '/') - Redirect[strlen(Redirect)-1] = '\0'; - - return(0); -} - -static int dodirsend(parms, np) -char *parms[]; -int np; -{ -char *file; -int i; -struct dirsend *pd, *lpd, *npd; - - if(np < 2) return(0); - - /* find end of the list */ - for(pd = dirsend, lpd = NULL; pd != NULL; lpd = pd, pd = pd->next) ; - - for(i = 1; i < np; i++) { - file = parms[i]; - if(file[0] == '#') break; - npd = malloc(sizeof(struct dirsend)); - if(npd == NULL) { - fprintf(stderr, "httpd: malloc failed in dodirsend\n"); - return(-1); - } - npd->file = malloc(strlen(file)+1); - if(npd->file == NULL) { - fprintf(stderr, "httpd: malloc failed in dodirsend\n"); - return(-1); - } - strcpy(npd->file, file); - npd->next = NULL; - if(lpd == NULL) - dirsend = npd; - else - lpd->next = npd; - lpd = npd; - } - - return(0); -} - -static int dodirexec(parms, np) -char *parms[]; -int np; -{ -char *file; - - if(np < 2) return(0); - - if(direxec != NULL) { - fprintf(stderr, "httpd: Error direxec line already present\n"); - return(-1); - } - - file = subvpath(parms[1]); - - direxec = malloc(strlen(file)+1); - - if(direxec == NULL) { - fprintf(stderr, "httpd: malloc failed in dodirexec\n"); - return(-1); - } - - strcpy(direxec, file); - - if(np > 2) - if(parms[2][0] != '#') { - fprintf(stderr, "httpd: garbage on end of direxec line\n"); - return(-1); - } - - return(0); -} - -static char *subvpath(s) -char *s; -{ -char *p, *p2; -int len; -static char buffer[1024]; -char user[80]; -struct passwd *pwd; - - /* replace beginning // with srvrroot */ - if(s[0] == '/' && s[1] == '/') - /* but not /// if we have VHOST's */ - if(vhost == NULL || s[2] != '/') { - strcpy(buffer, srvrroot); - strncat(buffer, s+1, sizeof(buffer) - strlen(buffer)); - buffer[sizeof(buffer)-1] = '\0'; - return(buffer); - } - - if(s[0] != '/' || s[1] != '~') return(s); - - /* replace beginning /~user with user home directory */ - p = s + 2; - p2 = user; - len = sizeof(user) - 1; - while(*p && *p != '/' && len-- > 0) *p2++ = *p++; - *p2 = '\0'; - if(*p != '\0' && *p != '/') return(s); - if((pwd = getpwnam(user)) == (struct passwd *)NULL) return(s); - strcpy(buffer, pwd->pw_dir); - strncat(buffer, p, sizeof(buffer) - strlen(buffer)); - buffer[sizeof(buffer)-1] = '\0'; - - return(buffer); -} - -static int dologfile(parms, np) -char *parms[]; -int np; -{ -char *p; - - if(np < 2) return(0); - - p = subvpath(parms[1]); - LogFile = malloc(strlen(p)+1); - if(LogFile == NULL) { - fprintf(stderr, "httpd: malloc failed in dologfile\n"); - return(-1); - } - strcpy(LogFile, p); - - return(0); -} - -static int dodbgfile(parms, np) -char *parms[]; -int np; -{ -char *p; - - if(np < 2) return(0); - - p = subvpath(parms[1]); - DbgFile = malloc(strlen(p)+1); - if(DbgFile == NULL) { - fprintf(stderr, "httpd: malloc failed in dodbgfile\n"); - return(-1); - } - strcpy(DbgFile, p); - - return(0); -} - -static int douser(parms, np) -char *parms[]; -int np; -{ - if(np < 2) return(0); - - User = malloc(strlen(parms[1])+1); - if(User == NULL) { - fprintf(stderr, "httpd: malloc failed in douser\n"); - return(-1); - } - strcpy(User, parms[1]); - - return(0); -} - -static int dochroot(parms, np) -char *parms[]; -int np; -{ -char *newroot; - - if(np < 2) return(0); - - newroot = subvpath(parms[1]); - - Chroot = malloc(strlen(newroot)+1); - if(Chroot == NULL) { - fprintf(stderr, "httpd: malloc failed in dochroot\n"); - return(-1); - } - strcpy(Chroot, newroot); - - return(0); -} - -static int adduser(pauth, user) -struct auth *pauth; -char *user; -{ -struct authuser *pa, *lpa, *newpa; - - for(pa = pauth->users, lpa = NULL; pa != NULL; lpa = pa, pa = pa->next) - ; - - newpa = malloc(sizeof(struct authuser)); - if(newpa == NULL) { - fprintf(stderr, "httpd: malloc failed in adduser\n"); - return(-1); - } - newpa->user = malloc(strlen(user)+1); - if(newpa->user == NULL) { - fprintf(stderr, "httpd: malloc failed in adduser\n"); - return(-1); - } - strcpy(newpa->user, user); - - newpa->next = NULL; - if(lpa == NULL) { - pauth->users = newpa; - newpa->next = pa; - } else { - lpa->next = newpa; - newpa->next = pa; - } - - return(0); -} - -static int doauth(parms, np) -char *parms[]; -int np; -{ -int i; -char *name, *desc, *pf; -char *p, *p2; -struct auth *pa, *lpa, *newpa; - - if(np < 3) return(0); - - name = parms[1]; - desc = parms[2]; - - for(pa = auth, lpa = NULL; pa != NULL; lpa = pa, pa = pa->next) - ; - - newpa = malloc(sizeof(struct auth)); - if(newpa == NULL) { - fprintf(stderr, "httpd: malloc failed in doauth\n"); - return(-1); - } - newpa->name = malloc(strlen(name)+1); - if(newpa->name == NULL) { - fprintf(stderr, "httpd: malloc failed in doauth\n"); - return(-1); - } - p = name; p2 = newpa->name; - while(*p) - *p2++ = tolower(*p++); - *p2 = '\0'; - - newpa->desc = malloc(strlen(desc)+1); - if(newpa->desc == NULL) { - fprintf(stderr, "httpd: malloc failed in doauth\n"); - return(-1); - } - strcpy(newpa->desc, desc); - - newpa->urlaccess = mkurlaccess(parms[3]); - newpa->passwdfile = NULL; - newpa->users = NULL; - - if(np > 4) - if(parms[4][0] != '#') { - if(!strcmp(parms[4], ".")) - pf = "/etc/passwd"; - else - pf = subvpath(parms[4]); - newpa->passwdfile = malloc(strlen(pf)+1); - if(newpa->passwdfile == NULL) { - fprintf(stderr, "httpd: malloc failed in doauth\n"); - return(-1); - } - strcpy(newpa->passwdfile, pf); - i = 5; - while(i < np) { - if(parms[i][0] == '#') - break; - if(adduser(newpa, parms[i])) - return(-1); - i++; - } - } - - newpa->next = NULL; - if(lpa == NULL) { - auth = newpa; - newpa->next = pa; - } else { - lpa->next = newpa; - newpa->next = pa; - } - - return(0); -} - -static int doproxyauth(parms, np) -char *parms[]; -int np; -{ -int i; -char *name, *desc, *pf; -char *p, *p2; -struct auth *pa, *lpa, *newpa; - - if(np < 3) return(0); - - name = parms[1]; - desc = parms[2]; - - if(proxyauth != (struct auth *)NULL) { - fprintf(stderr, "httpd: ProxyAuth defined multiple times using 1st only\n"); - return(0); - } - - for(pa = proxyauth, lpa = NULL; pa != NULL; lpa = pa, pa = pa->next) - ; - - newpa = malloc(sizeof(struct auth)); - if(newpa == NULL) { - fprintf(stderr, "httpd: malloc failed in doproxyauth\n"); - return(-1); - } - newpa->name = malloc(strlen(name)+1); - if(newpa->name == NULL) { - fprintf(stderr, "httpd: malloc failed in doproxyauth\n"); - return(-1); - } - p = name; p2 = newpa->name; - while(*p) - *p2++ = tolower(*p++); - *p2 = '\0'; - - newpa->desc = malloc(strlen(desc)+1); - if(newpa->desc == NULL) { - fprintf(stderr, "httpd: malloc failed in doproxyauth\n"); - return(-1); - } - strcpy(newpa->desc, desc); - - newpa->urlaccess = mkurlaccess(parms[3]); - newpa->passwdfile = NULL; - newpa->users = NULL; - - if(np > 4) - if(parms[4][0] != '#') { - if(!strcmp(parms[4], ".")) - pf = "/etc/passwd"; - else - pf = subvpath(parms[4]); - newpa->passwdfile = malloc(strlen(pf)+1); - if(newpa->passwdfile == NULL) { - fprintf(stderr, "httpd: malloc failed in doauth\n"); - return(-1); - } - strcpy(newpa->passwdfile, pf); - i = 5; - while(i < np) { - if(parms[i][0] == '#') - break; - if(adduser(newpa, parms[i])) - return(-1); - i++; - } - } - - newpa->next = NULL; - if(lpa == NULL) { - proxyauth = newpa; - newpa->next = pa; - } else { - lpa->next = newpa; - newpa->next = pa; - } - - return(0); -} diff --git a/commands/httpd0995/config.h b/commands/httpd0995/config.h deleted file mode 100644 index 7beeb8316..000000000 --- a/commands/httpd0995/config.h +++ /dev/null @@ -1,86 +0,0 @@ -/* config.h - * - * This file is part of httpd. - * - * 02/26/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * 07/04/2003 Al Woodhull - * 02/08/2005 Michael Temari - * 05/14/2006 Michael Temari - * - */ - -#define VERSION "Minix httpd 0.995" - -struct authuser { - char *user; - struct authuser *next; -}; - -struct auth { - char *name; - char *desc; - int urlaccess; - char *passwdfile; - struct authuser *users; - struct auth *next; -}; - -struct msufx { - char *suffix; - struct mtype *mtype; - struct msufx *snext; - struct msufx *tnext; -}; - -struct mtype { - char *mimetype; - struct msufx *msufx; - struct mtype *next; -}; - -struct vhost { - char *hname; - char *root; - struct vhost *next; -}; - -struct vpath { - char *from; - char *to; - struct auth *auth; - int urlaccess; - struct vpath *next; -}; - -struct dirsend { - char *file; - struct dirsend *next; -}; - -/* urlaccess bits */ - -#define URLA_READ 1 -#define URLA_WRITE 2 -#define URLA_EXEC 4 -#define URLA_HEADERS 8 - -#define HTTPD_CONFIG_FILE "/etc/httpd.conf" - -_PROTOTYPE(int readconfig, (char *cfg_file, int testing)); - -extern struct mtype *mtype; -extern struct msufx *msufx; -extern struct vhost *vhost; -extern struct vpath *vpath; -extern struct dirsend *dirsend; -extern struct auth *auth; -extern struct auth *proxyauth; -extern char *direxec; -extern char *srvrroot; -extern char *Redirect; -extern char *LogFile; -extern char *DbgFile; -extern char *User; -extern char *Chroot; diff --git a/commands/httpd0995/dir2html.c b/commands/httpd0995/dir2html.c deleted file mode 100644 index 36634d68a..000000000 --- a/commands/httpd0995/dir2html.c +++ /dev/null @@ -1,187 +0,0 @@ -/* dir2html.c by Michael Temari 3/3/96 */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -typedef struct namelist { /* Obviously a list of names. */ - struct namelist *next; - char name[1]; -} namelist_t; - -_PROTOTYPE(static void sort, (namelist_t **anl)); -_PROTOTYPE(static namelist_t *collect, (char *dir)); -_PROTOTYPE(int main, (int argc, char *argv[])); - -static void sort(anl) -namelist_t **anl; -/* A stable mergesort disguised as line noise. Must be called like this: - * if (L != NULL && L->next != NULL) sort(&L); - */ -{ - /* static */ namelist_t *nl1, **mid; /* Need not be local */ - namelist_t *nl2; - - nl1 = *(mid = &(*anl)->next); - do { - if ((nl1 = nl1->next) == NULL) break; - mid = &(*mid)->next; - } while ((nl1 = nl1->next) != NULL); - - nl2 = *mid; - *mid = NULL; - - if ((*anl)->next != NULL) sort(anl); - if (nl2->next != NULL) sort(&nl2); - - nl1 = *anl; - for (;;) { - if (strcmp(nl1->name, nl2->name) <= 0) { - if ((nl1 = *(anl = &nl1->next)) == NULL) { - *anl = nl2; - break; - } - } else { - *anl = nl2; - nl2 = *(anl = &nl2->next); - *anl = nl1; - if (nl2 == NULL) break; - } - } -} - -static namelist_t *collect(dir) -char *dir; -/* Return a sorted list of directory entries. Returns null with errno != 0 - * on error. - */ -{ - namelist_t *names, **pn = &names; - DIR *dp; - struct dirent *entry; - - if ((dp = opendir(dir)) == NULL) return NULL; - - while ((entry = readdir(dp)) != NULL) { - if (strcmp(entry->d_name, ".") == 0) continue; - *pn = malloc(offsetof(namelist_t, name) + strlen(entry->d_name) + 1); - if (*pn == NULL) { - closedir(dp); - errno = ENOMEM; - return NULL; - } - strcpy((*pn)->name, entry->d_name); - pn = &(*pn)->next; - } - closedir(dp); - *pn = NULL; - if (names != NULL && names->next != NULL) sort(&names); - errno = 0; - return names; -} - -int main(argc, argv) -int argc; -char *argv[]; -{ - namelist_t *np; - char *rpath, *vpath; - static char cwd[1024]; - static char work[64]; - char *filename; - struct stat st; - struct tm *tmp; - static char month[][4] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", - }; - - if(argc > 1) { - rpath = argv[1]; - if (chdir(rpath) < 0) { - fprintf(stderr, "dir2html: %s: %s\n", rpath, strerror(errno)); - return(-1); - } - } else { - if(getcwd(cwd, sizeof(cwd)) == NULL) { - fprintf(stderr, "dir2html: getcwd(): %s", strerror(errno)); - return(-1); - } - rpath = cwd; - } - - if(argc > 2) { - vpath = argv[2]; - } else { - vpath = rpath; - } - - if ((np = collect(".")) == NULL && errno != 0) { - fprintf(stderr, "dir2html: %s: %s\n", vpath, strerror(errno)); - return(-1); - } - - printf("Index of %s\n", vpath); - printf("\n"); - printf("

Index of %s

\n", vpath); - - printf("
\n");
-    printf("%-22s  %-17s  %s\n", "Name", "Last modified", "Size/Type");
-    printf("
\n"); - - while (np != NULL) { - errno = 0; - filename = np->name; - np= np->next; - - if (stat(filename, &st) < 0) continue; - - printf("", - filename, S_ISDIR(st.st_mode) ? "/" : ""); - sprintf(work, "%.23s%s", - filename, S_ISDIR(st.st_mode) ? "/" : ""); - if (strcmp(filename, "..") == 0) strcpy(work, "Parent Directory"); - printf("%-22.22s%s", - work, strlen(work) > 22 ? ">" : " "); - tmp = localtime(&st.st_mtime); - printf(" %02d %s %d %02d:%02d", - tmp->tm_mday, month[tmp->tm_mon], 1900+tmp->tm_year, - tmp->tm_hour, tmp->tm_min); - if (S_ISREG(st.st_mode)) { - if (st.st_size < 10240) { - sprintf(work, "%lu ", (unsigned long) st.st_size); - } else - if (st.st_size < 10240 * 1024L) { - sprintf(work, "%luK", - ((unsigned long) st.st_size - 1) / 1024 + 1); - } else { - sprintf(work, "%luM", - ((unsigned long) st.st_size - 1) / (1024 * 1024L) + 1); - } - } else { - strcpy(work, - S_ISDIR(st.st_mode) ? "[dir]" : - S_ISBLK(st.st_mode) ? "[block]" : - S_ISCHR(st.st_mode) ? "[char]" : - S_ISFIFO(st.st_mode) ? "[pipe]" : - "[???]"); - } - printf(" %8s\n", work); - } - - printf("
\n"); - - printf("
\n"); - printf("Minix httpd 0.99\n"); - printf("\n"); - printf("\n"); - - return(0); -} diff --git a/commands/httpd0995/dir2html.sh b/commands/httpd0995/dir2html.sh deleted file mode 100755 index 5a4b101fb..000000000 --- a/commands/httpd0995/dir2html.sh +++ /dev/null @@ -1,42 +0,0 @@ -# dir2html.sh by Michael Temari 03/03/96 -# -#!/bin/sh -if [ $# != 0 ] -then -cd $1 -fi -dname=`pwd` -fdname=$2 -if [ $dname != / ] -then - dname=${dname}/ -fi -echo "" -echo "" -echo Directory of $fdname -echo "" -echo "

" -echo Directory of $fdname -echo "

" -echo "
" -# -ls $dname | -{ -while read fname -do -lname=$fdname$fname -echo "

" -echo -n "" -echo -n $fname -echo "
" -echo "

" -done -} -echo "
" -echo "
" -echo Directory Generated at `date` -echo "
" -echo "" -exit 0 diff --git a/commands/httpd0995/http.h b/commands/httpd0995/http.h deleted file mode 100644 index bf868f3ab..000000000 --- a/commands/httpd0995/http.h +++ /dev/null @@ -1,118 +0,0 @@ -/* http.h - * - * This file is part of httpd. - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ - -#define INDEX_FILE_NAME "index.html" - -#define HTTP_REQUEST_TYPE_SIMPLE 0 -#define HTTP_REQUEST_TYPE_FULL 1 -#define HTTP_REQUEST_TYPE_PROXY 2 - -#define HTTP_METHOD_UNKNOWN 0 -#define HTTP_METHOD_OPTIONS 1 -#define HTTP_METHOD_GET 2 -#define HTTP_METHOD_HEAD 3 -#define HTTP_METHOD_POST 4 -#define HTTP_METHOD_PUT 5 -#define HTTP_METHOD_PATCH 6 -#define HTTP_METHOD_COPY 7 -#define HTTP_METHOD_MOVE 8 -#define HTTP_METHOD_DELETE 9 -#define HTTP_METHOD_LINK 10 -#define HTTP_METHOD_UNLINK 11 -#define HTTP_METHOD_TRACE 12 -#define HTTP_METHOD_WRAPPED 13 - -#define HTTP_STATUS_OK 200 -#define HTTP_STATUS_CREATED 201 -#define HTTP_STATUS_ACCEPTED 202 -#define HTTP_STATUS_NO_CONTENT 204 -#define HTTP_STATUS_MOVED_PERM 301 -#define HTTP_STATUS_MOVED_TEMP 302 -#define HTTP_STATUS_NOT_MODIFIED 304 -#define HTTP_STATUS_USE_PROXY 305 -#define HTTP_STATUS_BAD_REQUEST 400 -#define HTTP_STATUS_UNAUTHORIZED 401 -#define HTTP_STATUS_FORBIDDEN 403 -#define HTTP_STATUS_NOT_FOUND 404 -#define HTTP_STATUS_METHOD_NOT_ALLOWED 405 -#define HTTP_STATUS_PROXY_AUTH_REQRD 407 -#define HTTP_STATUS_LENGTH_REQUIRED 411 -#define HTTP_STATUS_SERVER_ERROR 500 -#define HTTP_STATUS_NOT_IMPLEMENTED 501 -#define HTTP_STATUS_BAD_GATEWAY 502 -#define HTTP_STATUS_SERVICE_UNAVAILABLE 503 -#define HTTP_STATUS_GATEWAY_TIMEOUT 504 -#define HTTP_STATUS_UNSUPPORTED_VERSION 505 - -struct http_request { - int type; - int method; - char uri[256]; - char url[256]; - char query[256]; - char host[256]; - int port; - char useragent[256]; - int vmajor; - int vminor; - time_t ifmodsince; - off_t size; - time_t msgdate; - int keepopen; - char wwwauth[128]; - char authuser[128]; - char authpass[128]; - char cookie[128]; -}; - -struct http_reply { - int status; - char statusmsg[128]; - int keepopen; - int headers; - char *mtype; - char realurl[256]; - struct auth *auth; - int urlaccess; - off_t size; - time_t modtime; - int fd; - int ofd; - int pid; -}; - -/* from httpd.c */ - -extern FILE *stdlog; -extern FILE *dbglog; - -/* from reply.c */ - -_PROTOTYPE(int sendreply, (struct http_reply *rp, struct http_request *rq)); - -/* from request.c */ - -_PROTOTYPE(int getrequest, (struct http_request *rq)); - -/* from process.c */ - -_PROTOTYPE(int processrequest, (struct http_request *rq, struct http_reply *rp)); - -/* from police.c */ - -_PROTOTYPE(int police, (struct http_request *rq, struct http_reply *rp)); - -/* from cgiexec.c */ - -_PROTOTYPE(int cgiexec, (struct http_request *rq, struct http_reply *rp)); - -/* from proxy.c */ - -_PROTOTYPE(void proxy, (struct http_request *rq, struct http_reply *rp)); diff --git a/commands/httpd0995/http_status.5 b/commands/httpd0995/http_status.5 deleted file mode 100644 index 5301a5793..000000000 --- a/commands/httpd0995/http_status.5 +++ /dev/null @@ -1,72 +0,0 @@ -.TH HTTP_STATUS 5 -.SH NAME -http_status \- HTTP status numbers and their meanings -.SH DESCRIPTION -These are the HTTP status numbers defined in -.BI http.h -in the source directory, -.BI /usr/local/src/httpdxxx. -The message you see on your screen when a page cannot be accessed is -normally generated by your browser. -.P -HTTP_STATUS_OK 200 -.br -HTTP_STATUS_CREATED 201 -.br -HTTP_STATUS_ACCEPTED 202 -.br -HTTP_STATUS_NO_CONTENT 204 -.br -HTTP_STATUS_MOVED_PERM 301 -.br -HTTP_STATUS_MOVED_TEMP 302 -.br -HTTP_STATUS_NOT_MODIFIED 304 -.br -HTTP_STATUS_USE_PROXY 305 -.br -HTTP_STATUS_BAD_REQUEST 400 -.br -HTTP_STATUS_UNAUTHORIZED 401 -.br -HTTP_STATUS_FORBIDDEN 403 -.br -HTTP_STATUS_NOT_FOUND 404 -.br -HTTP_STATUS_METHOD_NOT_ALLOWED 405 -.br -HTTP_STATUS_PROXY_AUTH_REQRD 407 -.br -HTTP_STATUS_LENGTH_REQUIRED 411 -.br -HTTP_STATUS_SERVER_ERROR 500 -.br -HTTP_STATUS_NOT_IMPLEMENTED 501 -.br -HTTP_STATUS_BAD_GATEWAY 502 -.br -HTTP_STATUS_SERVICE_UNAVAILABLE 503 -.br -HTTP_STATUS_GATEWAY_TIMEOUT 504 -.br -HTTP_STATUS_UNSUPPORTED_VERSION 505 -.br - -.SH FILES -.TP 25n -.B /usr/local/src/httpdxxx/http.h -.SH "SEE ALSO" -The definitive source of information on the HTTP protocol is the -.B "World Wide Web Consortium" -web page at -.B http://www.w3c.org . -.P -A draft version of the HTTP 1.1 specification is available on the Minix1 -websites. For more information on status codes go to this URL: -.B http://minix1.woodhull.com/http11.html#Status-Codes -.SH AUTHOR -The Minix httpd server was created by and is maintained by Michael Temari - -.P -Man page compiled by Al Woodhull -.\"updated 2006-06-01 diff --git a/commands/httpd0995/httpd.8 b/commands/httpd0995/httpd.8 deleted file mode 100644 index 04fed2a6a..000000000 --- a/commands/httpd0995/httpd.8 +++ /dev/null @@ -1,124 +0,0 @@ -.TH HTTPD 8 -.SH NAME -httpd, in.httpd, dir2html \- a web server for Minix 2 and Minix 3 -.SH SYNOPSIS -.B httpd -.RB [\-t|\-v] -.RI [ config_file ] -.P -.B "tcpd http /usr/local/bin/in.httpd &" -.P -.B dir2html -.RB [directory] -.SH DESCRIPTION -.B Httpd -is a World Wide Web (WWW) server written by Michael Temari. It was -written from scratch so the setup and configuration will not be like -other web servers. -.P -.B In.httpd -is linked to -.B httpd. -This alternate name is used to indicate the program is a server that is -started by -.B tcpd (8), -a program which listens for incoming TCP connections on the passed -port (defined in -.BI /etc/services ). -When a connection comes in -.B tcpd -forks and starts the given daemon program, after possibly checking for access -restrictions and logging the connection. Therefore, to enable -.B in.httpd -to start you use (in a startup script): -.P -.B "tcpd http /usr/local/bin/in.httpd &" -.P -or -.P -.B "daemonize tcpd http /usr/local/bin/in.httpd" -.P -.B (daemonize -is a shell function defined in -.BI/usr/etc/rc -in Minix 2.0.3 and later releases which starts programs as daemons). -To enable or reenable -.B in.httpd -from the command line a user a system administrator should use -.B intr (8), -like this: -.P -.B "intr -d tcpd http /usr/local/bin/in.httpd &" -.P -to start -.B tcpd -as a daemon (getting input from /dev/null, writing output to /dev/log, -and not part of a process group). -.P -.B Dir2html -is an accessory program that produces a directory listing formatted as -web page for the current directory or for a directory specified as an -argument. It is called by -.B httpd -when a web client references a directory that includes no index.html -file (or whatever alternative to index.html that may be defined in -/etc/httpd.conf). Since it writes to standard output it may also be called -as a standalone program. -.P -Options for -.B httpd -are: -.SH OPTIONS -.TP -.B \-t -This tells the server to parse the configuration file so that you can -see if it is the way you want it. You may also pass the name of your -configuration file if it is not the default /etc/httpd.conf. -.TP -.B \-v -Shows the server version, then exits. -.TP -.B config_file -normally /etc/httpd.conf -.SH FILES -.TP 25n -.B /etc/httpd.conf -The configuration file. -.P -.B /etc/httpd.mtype -Extension to configuration file defining MIME types. -.P -.B /usr/adm/httpd.log -Log file. The file must exist for logging to begin. -.SH "SEE ALSO" -.BR httpd.conf (5), -.BR http_status (5), -.BR serv.access (5), -.BR intr (8), -.BR tcpd (8). -.SH NOTES -This server has been tested on both Minix 2 and Minix 3. -.P -Running a server exposed to the Internet is risky to the host system and -to the local network. Consult with the owner of your net before you go -public. Read the -.B SECURITY -document in the source directory. -.P -The -.B tcpd (8) -man page needs to be written. The important thing to know is that if -the access control file -.B /etc/serv.access -exists tcpd will exec its paranoid twin, tcpdp, which will deny access from -any IP for which a name cannot be found. -.SH BUGS -None are known, but there are surely some unknown ones. Be careful! -.SH AUTHOR -The Minix httpd server was created by and is maintained by Michael Temari - -.P -This man page was compiled by Al Woodhull -.P -.\" updated 2006-06-17 - diff --git a/commands/httpd0995/httpd.c b/commands/httpd0995/httpd.c deleted file mode 100644 index bbe767264..000000000 --- a/commands/httpd0995/httpd.c +++ /dev/null @@ -1,175 +0,0 @@ -/* httpd.c - * - * httpd A Server implementing the HTTP protocol. - * - * usage: tcpd http httpd & - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * 07/04/2003 Al Woodhull - * - */ - -#include -#include -#include -#include -#include -#include -#include "http.h" -#include "utility.h" -#include "net.h" -#include "config.h" - -FILE *stdlog = (FILE *)NULL; -FILE *dbglog = (FILE *)NULL; - -char umsg[80]; - -_PROTOTYPE(int main, (int argc, char *argv[])); - -struct http_request request; -struct http_reply reply; - -int main(argc, argv) -int argc; -char *argv[]; -{ -char *prog; -int opt_t; -char *cfg = (char *)NULL; -struct passwd *pwd; -int s; - - strcpy(umsg, "Usage: "); - strcat(umsg, argv[0]); - strcat(umsg, " [-t|v] [config_file]\n"); - - /* parse program name */ - prog = strrchr(*argv, '/'); - if(prog == (char *)NULL) - prog = *argv; - else - prog++; - argv++; - argc--; - - /* Any options */ - if(argc) - if(argv[0][0] == '-') { - switch (argv[0][1]) { - case 't' : opt_t = 1; - argv++; - argc--; - break; - case 'v' : fprintf(stderr, VERSION"\n"); - exit(EXIT_SUCCESS); - break; - default : fprintf(stderr, VERSION"\n"); - fprintf(stderr, umsg); - exit(EXIT_FAILURE); - } - } - - /* Did they specify an alternate configuration file? */ - if(argc) { - cfg = *argv++; - argc--; - } - - /* Read the configuration settings */ - if(readconfig(cfg, opt_t)) { - fprintf(stderr, "httpd: Error reading configuration file.\n"); - return(-1); - } - - /* Option t is to test configuration only */ - if(opt_t) - return(0); - - /* Open log file for append if it exists */ - if(LogFile != NULL) - if((stdlog = fopen(LogFile, "r")) != (FILE *)NULL) { - fclose(stdlog); - stdlog = fopen(LogFile, "a"); - } - - /* Open debug log file for append if it exists */ - if(DbgFile != NULL) - if((dbglog = fopen(DbgFile, "r")) != (FILE *)NULL) { - fclose(dbglog); - dbglog = fopen(DbgFile, "a"); - } - -#if 0 - /* Get some network information */ - GetNetInfo(); -#endif - - /* If user defined then prepare to secure as user given */ - if(User != NULL) - if((pwd = getpwnam(User)) == (struct passwd *)NULL) { - fprintf(stderr, "httpd: unable to find user %s\n", User); - return(-1); - } - - /* If Chroot defined then secure even more by doing a chroot */ - if(Chroot != NULL) { - if(chroot(Chroot)) { - fprintf(stderr, "httpd: unable to chroot\n"); - return(-1); - } - if(chdir("/")) { - fprintf(stderr, "httpd: unable to chroot\n"); - return(-1); - } - } - - /* If user defined then secure as user given */ - if(User != NULL) - if(setgid(pwd->pw_gid) || setuid(pwd->pw_uid)) { - fprintf(stderr, "httpd: unable to set user\n"); - return(-1); - } - -#if DAEMON - /* Standalone? */ - if (strncmp(prog, "in.", 3) != 0) { - /* Does not start with "in.", so not started from inetd/tcpd. */ - /* XXX - Port name/number should be a config file option. */ - daemonloop("http"); - } -#endif - - /* Get some network information */ - GetNetInfo(); - - /* log a connection */ - if(dbglog != (FILE *)NULL) { - fprintf(dbglog, "CONNECT: %d %s %s\n", getpid(), - rmthostname, logdate((time_t *)NULL)); - fflush(dbglog); - } - - /* loop getting, processing and replying to requests */ - while(!(s = getrequest(&request))) { - if(processrequest(&request, &reply)) break; - if(stdlog != (FILE *)NULL) { - fprintf(stdlog, "%s %s %d %d %s\n", - logdate((time_t *)NULL), rmthostname, - request.method, reply.status, request.url); - fflush(stdlog); - } - if(sendreply(&reply, &request)) break; - if(!reply.keepopen) break; - } - if(s == 1 && stdlog != (FILE *)NULL) { - fprintf(stdlog, "%s %s %d %d %s\n", - logdate((time_t *)NULL), rmthostname, - request.method, 999, request.url); - fflush(stdlog); - } - - return(0); -} diff --git a/commands/httpd0995/httpd.conf b/commands/httpd0995/httpd.conf deleted file mode 100644 index 78a2d877b..000000000 --- a/commands/httpd0995/httpd.conf +++ /dev/null @@ -1,166 +0,0 @@ -# httpd.conf Sample httpd.conf file By Michael Temari 2006-06-01 - -#serverroot path -# -# path = sets the translation for // -# -# these have special meaning if at beginning of path -# -# /~user = gets replaced with user home directory - -#redirect http://SomeWhere.Else.Com/ - -#redirect url -# -# url = Will redirect entire website via error code 301 MOVED PERM to -# url and original url path of request. - -serverroot /~www - -#user username -# -# if present the server will run as the given username otherwise the -# server will run as who ever started it (normally root). - -user www - -#chroot directory -# -# if present the server will be chroot'ed to the given directory name -# normally the home directory of username given above. Be aware if this -# is set then you can only access stuff off this new root. -# -# these have special meaning if at beginning of the directory -# -# // = gets replaced by serverroot directory -# /~user = gets replaced with user home directory - -#chroot /~www - -#logfile filename -# -# the file must exist also and a log of http transactions will be kept -# -# these have special meaning if at the beginning of the filename -# -# // = gets replaced by serverroot directory -# /~user = gets replaced with user home directory - -logfile /usr/adm/httpd.log - -#dbgfile filename -# -# the file must exist also and a debug log of http transactions will be kept -# -# these have special meaning if at the beginning of the filename -# -# // = gets replaced by serverroot directory -# /~user = gets replaced with user home directory - -dbgfile /usr/adm/httpd.dbg - -# dirsend [list of files to try until 1st one is found] -# - -dirsend index.htm - -# direxec [script to run for automatic directory page output] -# -# -# these have special meaning if at beginning of script -# -# // = gets replaced by serverroot directory -# /~user = gets replaced with user home directory -# - -direxec /usr/local/bin/dir2html - -# vhost hostname VhostRoot -# -# vhost is for defining access for virtual hosts. If none are configured then -# any host is accepted. If specified then access is only granted for requests -# for hosts which are configured here. In the Vpath section below the /// gets -# translated to the corresponding VhostRoot. - -# vhost temware.dyndns.org //doc/ -# vhost minix.homeip.net //doc2/ - -# auth authname authdescription access [passwdfile [users]] -# -# auth defines any access authorization to be used in vpath -# -# authname = name to give to this authorization (case insensitive) -# authdescription = Description of this authorization -# access = r=read, w=write, x=execute, h=headers (other than rwxh then no access) -# NOTE: r=file should be read, w=file can be overwrote -# NOTE: x=file should be executed -# NOTE: h=headers (executing program will produce all http headers) -# NOTE: access is on top of unix access -# passwdfile = Name of passwd file to be used (. means /etc/passwd) -# (if none given then no user check) -# users = valid users for this authorization (if none given then all users valid) -# -# these have special meaning if at beginning of passwdfile -# -# // = gets replaced by serverroot directory -# /~user = gets replaced with user home directory -# - -auth AnyBody AnyBody R - System System_User R . - Uploads Uploads RW . root - -# proxyauth authname authdescription access [passwdfile [users]] -# -# proxyauth defines any access authorization to be used for Proxy access -# -# authname = Same as auth above -# authdescription = Same as auth above -# access = Must be R to allow proxy -# passwdfile = Same as auth above -# users = Same as auth above -# - -# proxyauth -# Proxy Proxy R . - - -# vpath from to auth -# -# vpath sets up a list of url path translations and authorizations -# -# from = user specified url -# *=wildcard, $=wildard, but keep path for passing to program -# to = real location -# auth = authname from above (null for no authorization) -# access = r-read, w-write, x-execute (if not given taken from auth record) -# = h-headers (executing program will produce all http headers) -# -# these have special meaning if at beginning of to or serverroot fields -# -# // = gets replaced by serverroot directory -# /// = gets replaced by vhost root directory if configured otherwise same as // -# . = specified authorization only, use other translation elsewhere -# /~user = gets replaced with user home directory -# - -vpath * . AnyBody - /* /// AnyBody - /index.htm . AnyBody X - /ip . AnyBody X - /c1d1$ //exec/cdrom AnyBody X - /c1d2$ //exec/cdrom AnyBody X - /uploads* . Uploads - /src* /usr/src AnyBody R - -# include filename -# -# include tells the server to continue parsing configuration information -# in the given filename -# -# these have special meaning if at beginning of filename -# -# // = gets replaced by serverroot directory -# /~user = gets replaced with user home directory - -include //etc/httpd.mtype diff --git a/commands/httpd0995/httpd.conf.5 b/commands/httpd0995/httpd.conf.5 deleted file mode 100644 index c8b96c180..000000000 --- a/commands/httpd0995/httpd.conf.5 +++ /dev/null @@ -1,334 +0,0 @@ -.TH HTTPD.CONF 5 -.SH NAME -httpd.conf httpd.mtype \- configuration files for the Minix httpd web server -.SH SYNOPSIS -.B /etc/httpd.conf -.B /etc/httpd.mtype -.SH DESCRIPTION -.B /etc/httpd.conf -is the configuration file for the Minix httpd web server written by -Michael Temari. A sample version is included with the distribution -archive and is unpacked in the source directory (normally -.BI /usr/local/src/httpdxxx). -Also provided is an example -.B httpd.mtype -file. This is an extension of the main configuration file which is normally -included when the main file is read. -.P -The makefile does not install -.B httpd.conf -and -.B httpd.mtype -automatically. The sample files included in the distribution are only -examples, you must copy and edit them for the needs of your own -installation. -.SH CONFIGURATION FILE FORMAT -.B httpd.conf -is an ascii file which consists of lines of the following form: -.P -.B directive LWS [parameters separated by LWS] -.br -NOTE: LWS denotes Linear White Space which is spaces and/or tabs -.SH CONFIGURATION FILE DIRECTIVES -The following are valid configuration file directives (listed in the order -they appear in the sample -.B httpd.conf -file provided in the distribution): -.P -.B serverroot redirect user chroot logfile dbgfile dirsend direxec -.B vhost auth proxyauth vpath include mtype -.P -To make the file more readable, for directives which occupy multiple -lines you may eliminate the directive on lines after the first and begin -these lines with LWS. - -.SH DESCRIPTIONS OF DIRECTIVES -.P -.B serverroot path - -The -.B serverroot -directive sets the translation for -.B // -to the given -.B path. - -.B redirect url - -The -.B redirect -directive will redirect the entire website via error code -"301 MOVED PERM" to specified url and original path of request. - -.B user username - -The -.B user -directive causes the server to run as the given -.B username -otherwise the server will run as whoever started it (normally root). - -.B chroot directory - -The -.B chroot -directive causes the server to chroot to the given directory after -the configuration and log files have been opened. Normally this will be the -home directory of the given username in the user directive. -.br -NOTE: -.B /~user -will be translated to the home directory of -.B user. -.br -NOTE: -.B // -will be translated to the serverroot directory. -.br -NOTE: if this directive is used then beware of the consequences. - -.B logfile filename - -The -.B logfile -directive tells the server where to log http transactions. -.br -NOTE: the log file must exist to enable logging. - -.B dbgfile filename - -The -.B dbgfile -directive tells the server where to log debugging of http transactions. -.br -NOTE: the debug log file must exist to enable debug logging. - -.B dirsend filelist - -The -.B dirsend -directive tells the server that when a directory is requested -that it should send the first file that it finds in the directory from the -.B filelist -for the request. - -.B direxec program - -The -.B direxec -directive tells the server that when a directory is requested -and no file is found from the -.B dirsend -directive that it should run the given -.B program. -.br -NOTE: the program normally generates a directory listing on the fly using -the -.B dir2html -program. -.br -NOTE: the program access is considered -.B X -with no access restrictions. - -.B vhost hostname vhostroot - -The -.B vhost -directive is for defining access for virtual hosts. If none are configured -then any host is accepted. If specified then access is only granted for -requests for hosts which are configured here. In the -.B vpath -section below the -.B /// -gets translated to the corresponding -.B vhostroot. - - -.B auth authname authdescription access [passwdfile [users]] - -The -.B auth -directive sets up different authorizations with the server. The -.B authname -is the name given to the authorization and is case insensitive. -The -.B authdescription -is the description of the authorization and is what -the user will see when asked to enter a username and password. The -access is one or more of -.B (RWX). -.B R -tells the server the URL can be read. -.B W -tells the server the URL can be overwritten. -.B X -tells the server -that the URL can and should be executed. Access is in addition to normal -Unix security considerations. For instance a file that can be written to -that does not have the -.B W -access will have an error returned. The -.B passwdfile -is the name of the password file to validate users against. If -.B passwdfile -is given as -.B '.' -then the system password file -.B (/etc/passwd) -will be used. If no -.B passwdfile -is given then no authorization is allowed for anyone. If no -.B users -are given then any validated user is authorized, otherwise only the given -.B users -are allowed. - -.B proxyauth authname authdescription access [passwdfile [users]] - -The -.B proxyauth -directive defines access authorization to be used for Proxy access. -.br -.B authname -= Same as auth above -.br -.B authdescription -= Same as auth above -.br -.B access -= Must be R to allow proxy -.br -.B passwdfile -= Same as auth above -.br -.B users -= Same as auth above - -.B vpath from to [auth [access]] - -The -.B vpath -directive sets up URL path translations and authorizations. A -requested URL that matches -.B from -will be translated to -.B to -with the given -.B auth -and -.B access. -If -.B auth -does not exist then the URL will have no -.B access. -If -.B access -is not given then the access is taken from the -.B auth -record (see above). A -.B '.' -in place of the -.B to -means that the server should use a translation from another -.B vpath -record, but associate the given -.B auth -and access with the requested URL. A -.B '*' -may be at the end only of the -.B from -to provide a wildcard match. For example if the -.B from -has -.B /AB* -then any of -.B /ABCDEF -or -.B /AB -or -.B /ABmichael -will match, but -.B /AD or -.B /a -will not. The requested URL is first checked against each -.B vpath -record until an exact match (meaning URL match -.B from -and -.B from -had no -.B '*') -is found or the end of the list. Therefore a wildcard match will match -the last -.B from in the list in which it matched. -.br -NOTE: if at the beginning of the to field -.br - /~user will get translated to the home directory of the given user -.br - // will get translated to the serverroot directory - -.B include filename - -The -.B include -directive tells the server to read configuration information -from the given filename. -.br -NOTE: normally you get -.B mtype -directives in an included file. - -.B mtype mimetype extensions - -The -.B mtype -directive tells the server what -.B mimetype -to associate with files which have any of the given -.B extensions. -If no match is found then the file will be treated as -.B application/octet-stream. - - -.SH FILES -.B /etc/httpd.conf -.B /etc/httpd.mtype -.B /etc/passwd -.SH "SEE ALSO" -.BR httpd (8) -.BR http_status (5) -.SH NOTES -The source directory contains a commented sample -.B httpd.conf -and -.B httpd.mtype -files. -.P -You can run the server as -.B httpd -t /etc/httpd.conf -to see whether the configuration file is being parsed correctly. -.P -Although standard Minix does not have a graphical interface to support -browsers such as Netscape and Microsoft Internet Explorer, the -.B lynx -browser can be used on 32-bit Minix systems with enough memory. You can point -lynx to your own site to browse your own pages. -When debugging a web server there is nothing quite like browsing your own -pages to see whether things are working right. That said, be aware that -different web browsers may vary in how they interpet standard web page -features, and will certainly vary in how they interpret "extensions" to -the HTML standards. So checking a page with several browsers on several -platforms is always a good idea. -.SH BUGS -Not really a bug, but you can get in trouble if a real directory you want -to access shares the first part of its name with a -.B vpath -definition. You just have to pay attention to the directory names you use. -.SH AUTHOR -The Minix httpd server was created by and is maintained by Michael Temari - -.P -Man page was compiled by Al Woodhull -.\" updated 2006-06-01 diff --git a/commands/httpd0995/httpd.mtype b/commands/httpd0995/httpd.mtype deleted file mode 100644 index d39335ad1..000000000 --- a/commands/httpd0995/httpd.mtype +++ /dev/null @@ -1,40 +0,0 @@ -# mime types By Michael Temari 12/29/2002 Ver 0.40 - -# if a file extension is not found in the configuration below the default -# mime type will be application/octet-stream. This default can be changed -# by entering a line with a mime type only with no extension. - -mtype - application/octet-stream - application/compress .Z - application/msword .doc - application/octet-stream .bin .exe - application/pdf .pdf - application/postscript .ps .ai .eps - application/smil .smil - application/x-gtar .gtar - application/x-gzip .gz - application/x-sh .sh - application/x-pn-realaudio .ra .ram - application/x-tar .tar - application/zip .zip - audio/basic .au .snd - audio/mpeg .mp3 - audio/x-aiff .aif .aiff .aifc - audio/x-midi .mid - audio/x-wav .wav - image/bmp .bmp - image/gif .gif - image/jpeg .jpg .jpeg .jpe - image/png .png - image/tiff .tiff .tif - image/x-rgb .rgb - image/x-xbitmap .xbm - multipart/x-www-form-urlencoded .wfu - text/html .html .htm - text/plain .txt .c .h - text/richtext .rtf .rtx - video/mpeg .mpg .mpeg .mpe - video/quicktime .qt .mov - video/x-msvideo .avi - video/x-sgi-movie .movie diff --git a/commands/httpd0995/httpd0995.txt b/commands/httpd0995/httpd0995.txt deleted file mode 100644 index fc30e9a14..000000000 --- a/commands/httpd0995/httpd0995.txt +++ /dev/null @@ -1,59 +0,0 @@ -httpd0995 --- A www server for Minix 2 and Minix 3 -written by Michael Temari release 0.995 2006-05-14 - -Httpd is a World Wide Web (WWW) server. I wrote it from scratch so -the setup and configuration will not be like other web servers though -hopefully by reading this document there will be no problems in getting -my web server up and running on your Minix system. - -Earlier versions of this web server were in use for many years on -minix1.hampshire.edu and minix1.bio.umass.edu. - -Installation: unpack the tarball in /usr/local/src or another directory -of your choice: - - zcat < httpd0995.taz | tar xvfp - - -An httpd0995 directory will be created and files will be unpacked -there. The README file explains compilation, installation, -configuration, and use. Please also read the SECURITY file if you plan -to make your system accessible over the net. - -Changes for release 0.995: - -- a redirect capability has been added. If redirect is defined in the -configuration file then all request url's will be redirected to that -host with the original request. For instance, if in the configuration -file of minix1.hampshire.edu this line appears: - redirect http://minix1.woodhull.com/ -a request of http://minix1.hampshire.edu/some/page will return a 301 error -which is a redirect permanent to: http://minix.woodhull.com/some/page - -- several documentation files and man pages have been updated. - -Changes for release 0.994: - -- calling CGI programs has been made more secure. - -Changes for release 0.993: - -- a new method of authorizing proxy. You will no longer need the Proxy -entry in Auth and can remove the http://* entry in vpath. The old way -allowed for having different authorizations depending on what URLs were -asked for via proxy, i.e., you could allow proxy access only to -http:://www.hampshire.edu/. Now it is just a simple authorization for -allowing proxy or not. - -- avoids using a Minix 2.0.3 library call that was not present in Minix -2.0.2, and thus can be compiled with either of the two most recent -Minix releases. - -- a -v option has been added to display the current version then exit. - -- man pages added, other documentation updated. - -Changes for release 0.99: You can set a default in the httpd.mtype -file. A mime type with no extensions on a line will be the default. -Previously recompilation was needed to change the default mime type. - -updated 2006-06-01 (ASW) diff --git a/commands/httpd0995/net.c b/commands/httpd0995/net.c deleted file mode 100644 index 4d2638593..000000000 --- a/commands/httpd0995/net.c +++ /dev/null @@ -1,240 +0,0 @@ -/* net.c - * - * This file is part of httpd. - * - * 01/25/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "net.h" - -_PROTOTYPE(static void release, (int *fd)); - -ipaddr_t myipaddr, rmtipaddr; -tcpport_t myport, rmtport; -char myhostname[256]; -char rmthostname[256]; -char rmthostaddr[3+1+3+1+3+1+3+1]; - -void GetNetInfo() -{ -nwio_tcpconf_t tcpconf; -int s; -struct hostent *hostent; - - /* Ask the system what our hostname is. */ - if(gethostname(myhostname, sizeof(myhostname)) < 0) - strcpy(myhostname, "unknown"); - - /* lets get our ip address and the clients ip address */ - s = ioctl(0, NWIOGTCPCONF, &tcpconf); - if(s < 0) { - myipaddr = 0; - myport = 0; - rmtipaddr = 0; - rmtport = 0; - strcpy(rmthostname, "??Unknown??"); - strcpy(rmthostaddr, "???.???.???.???"); - return; - } - - myipaddr = tcpconf.nwtc_locaddr; - myport = tcpconf.nwtc_locport; - rmtipaddr = tcpconf.nwtc_remaddr; - rmtport = tcpconf.nwtc_remport; - - /* Look up the host name of the remote host. */ - hostent = gethostbyaddr((char *) &rmtipaddr, sizeof(rmtipaddr), AF_INET); - if(!hostent) - strncpy(rmthostname, inet_ntoa(rmtipaddr), sizeof(rmthostname)-1); - else - strncpy(rmthostname, hostent->h_name, sizeof(rmthostname)-1); - - strcpy(rmthostaddr, inet_ntoa(rmtipaddr)); - - rmthostname[sizeof(rmthostname)-1] = '\0'; - - return; -} - -static void release(fd) -int *fd; -{ - if(*fd != -1) { - close(*fd); - *fd= -1; - } -} - -void daemonloop(service) -char *service; -{ -tcpport_t port; -struct nwio_tcpcl tcplistenopt; -struct nwio_tcpconf tcpconf; -struct nwio_tcpopt tcpopt; -struct servent *servent; -char *tcp_device; -int tcp_fd, client_fd, r; -int pfd[2]; -unsigned stall= 0; - - if((servent= getservbyname(service, "tcp")) == NULL) { - unsigned long p; - char *end; - - p = strtoul(service, &end, 0); - if(p <= 0 || p > 0xFFFF || *end != 0) { - fprintf(stderr, "httpd: %s: Unknown service\n", service); - exit(1); - } - port= htons((tcpport_t) p); - } else - port= servent->s_port; - - /* No client yet. */ - client_fd= -1; - - while (1) { - if((tcp_device = getenv("TCP_DEVICE")) == NULL) - tcp_device = TCP_DEVICE; - if ((tcp_fd= open(tcp_device, O_RDWR)) < 0) { - fprintf(stderr, "httpd: Can't open %s: %s", - tcp_device, strerror(errno)); - if (errno == ENOENT || errno == ENODEV - || errno == ENXIO) { - exit(1); - } - goto bad; - } - - tcpconf.nwtc_flags= NWTC_LP_SET | NWTC_UNSET_RA | NWTC_UNSET_RP; - tcpconf.nwtc_locport= port; - - if (ioctl(tcp_fd, NWIOSTCPCONF, &tcpconf) < 0) { - fprintf(stderr, "httpd: Can't configure TCP channel", - strerror(errno)); - exit(1); - } - -#ifdef NWTO_DEL_RST - tcpopt.nwto_flags= NWTO_DEL_RST; - - if (ioctl(tcp_fd, NWIOSTCPOPT, &tcpopt) < 0) { - fprintf(stderr, "httpd: Can't set TCP options", - strerror(errno)); - exit(1); - } -#endif - - if (client_fd != -1) { - /* We have a client, so start a server for it. */ - -#ifdef NWTO_DEL_RST - tcpopt.nwto_flags= 0; - (void) ioctl(client_fd, NWIOSTCPOPT, &tcpopt); -#endif - - fflush(NULL); - - /* Create a pipe to serve as an error indicator. */ - if (pipe(pfd) < 0) { - fprintf(stderr, "httpd: pipe", strerror(errno)); - goto bad; - } - - /* Fork twice to daemonize child. */ - switch (fork()) { - case -1: - fprintf(stderr, "httpd: fork", strerror(errno)); - close(pfd[0]); - close(pfd[1]); - goto bad; - case 0: - close(tcp_fd); - close(pfd[0]); - switch (fork()) { - case -1: - fprintf(stderr, "httpd: fork", - strerror(errno)); - write(pfd[1], &errno, sizeof(errno)); - exit(1); - case 0: - break; - default: - exit(0); - } - dup2(client_fd, 0); - dup2(client_fd, 1); - close(client_fd); - close(pfd[1]); - - /* Break out of the daemon loop, continuing with - * the normal httpd code to serve the client. - */ - return; - - default: - release(&client_fd); - close(pfd[1]); - wait(NULL); - r= read(pfd[0], &errno, sizeof(errno)); - close(pfd[0]); - if (r != 0) goto bad; - break; - } - } - - /* Wait for a new connection. */ - tcplistenopt.nwtcl_flags= 0; - - while (ioctl(tcp_fd, NWIOTCPLISTEN, &tcplistenopt) < 0) { - if (errno != EAGAIN) { - fprintf(stderr, "httpd: Unable to listen: %s", - strerror(errno)); - } - goto bad; - } - - /* We got a connection. */ - client_fd= tcp_fd; - tcp_fd= -1; - - /* All is well, no need to stall. */ - stall= 0; - continue; - - bad: - /* All is not well, release resources. */ - release(&tcp_fd); - release(&client_fd); - - /* Wait a bit if this happens more than once. */ - if (stall != 0) { - sleep(stall); - stall <<= 1; - } else { - stall= 1; - } - } -} diff --git a/commands/httpd0995/net.h b/commands/httpd0995/net.h deleted file mode 100644 index 255fd051b..000000000 --- a/commands/httpd0995/net.h +++ /dev/null @@ -1,17 +0,0 @@ -/* net.h - * - * This file is part of httpd. - * - * - * 01/25/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ - -_PROTOTYPE(void GetNetInfo, (void)); -_PROTOTYPE(void daemonloop, (char *service)); - -extern char myhostname[256]; -extern char rmthostname[256]; -extern char rmthostaddr[3+1+3+1+3+1+3+1]; diff --git a/commands/httpd0995/pass.c b/commands/httpd0995/pass.c deleted file mode 100644 index c7011322e..000000000 --- a/commands/httpd0995/pass.c +++ /dev/null @@ -1,213 +0,0 @@ -/* pass.c - * - * This file is part of httpd. - * - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef _MINIX -#include -#endif - -#define STD_PASSWD_FILE "/etc/passwd" - -#include "pass.h" - -static char buffer[1024]; -static char *pwduser; -static char *pwdpass; -static char *pwde[4]; - -_PROTOTYPE(static int getuser, (char *pwdfile, char *user)); - -static int getuser(pwdfile, user) -char *pwdfile; -char *user; -{ -FILE *fp; -char *p; -int i; - - if((fp = fopen(pwdfile, "r")) == (FILE *)NULL) - return(-1); - - for(i = 0; i < 4; i ++) pwde[i] = ""; - - while(1) { - if(fgets(buffer, sizeof(buffer), fp) == (char *)NULL) { - fclose(fp); - return(-1); - } - p = buffer; - pwduser = p; - while(*p && *p != ':') p++; - if(*p != ':') continue; - *p++ = '\0'; - if(strcmp(pwduser, user)) continue; - pwdpass = p; - while(*p && *p != ':' && *p != '\r' && *p != '\n') p++; - if(*p == ':') - *p++ = '\0'; - else { - if(*p) *p = '\0'; - fclose(fp); - } - for(i = 0; i < 4; i++) { - pwde[i] = p; - while(*p && *p != ':' && *p != '\r' && *p != '\n') p++; - if(*p == ':') - *p++ = '\0'; - else { - if(*p) *p = '\0'; - break; - } - } - fclose(fp); - - return(0); - } -} - -int passfile(pwdfile) -char *pwdfile; -{ -FILE *fp; - - if(!strcmp(pwdfile, STD_PASSWD_FILE)) - return(0); - - if((fp = fopen(pwdfile, "r")) == (FILE *)NULL) - return(-1); - - fclose(fp); - - return(0); -} - -int passuser(pwdfile, user) -char *pwdfile; -char *user; -{ - if(!strcmp(pwdfile, STD_PASSWD_FILE)) - if(getpwnam(user) == (struct passwd *)NULL) - return(-1); - else - return(0); - - return(getuser(pwdfile, user)); -} - -int passnone(pwdfile, user) -char *pwdfile; -char *user; -{ -struct passwd *pwd; - - if(!strcmp(pwdfile, STD_PASSWD_FILE)) - if((pwd = getpwnam(user)) == (struct passwd *)NULL) - return(-1); - else - if(!strcmp(pwd->pw_passwd, crypt("", pwd->pw_passwd))) - return(-1); - else - return(0); - - if(getuser(pwdfile, user)) - return(-1); - - if(!strcmp(pwdpass, crypt("", pwdpass))) - return(-1); - else - return(0); -} - -int passpass(pwdfile, user, pass) -char *pwdfile; -char *user; -char *pass; -{ -struct passwd *pwd; - - if(!strcmp(pwdfile, STD_PASSWD_FILE)) - if((pwd = getpwnam(user)) == (struct passwd *)NULL) - return(-1); - else - if(strcmp(pwd->pw_passwd, crypt(pass, pwd->pw_passwd))) - return(-1); - else - return(0); - - if(getuser(pwdfile, user)) - return(-1); - - if(strcmp(pwdpass, crypt(pass, pwdpass))) - return(-1); - else - return(0); -} - -int passadd(pwdfile, user, pass, e1, e2, e3, e4) -char *pwdfile; -char *user; -char *pass; -char *e1; -char *e2; -char *e3; -char *e4; -{ -FILE *fp; -time_t salt; -char sl[2]; -int cn; -char *ee1; -char *ee2; -char *ee3; -char *ee4; - - - if(pwdfile == (char *)NULL || - user == (char *)NULL || - pass == (char *)NULL) - return(PASS_ERROR); - - if(!strcmp(pwdfile, STD_PASSWD_FILE)) - return(PASS_ERROR); - - if(!getuser(pwdfile, user)) - return(PASS_USEREXISTS); - - time(&salt); - sl[0] = (salt & 077) + '.'; - sl[1] = ((salt >> 6) & 077) + '.'; - for (cn = 0; cn < 2; cn++) { - if (sl[cn] > '9') sl[cn] += 7; - if (sl[cn] > 'Z') sl[cn] += 6; - } - - if(e1 == (char *)NULL) ee1 = ""; else ee1 = e1; - if(e2 == (char *)NULL) ee2 = ""; else ee2 = e2; - if(e3 == (char *)NULL) ee3 = ""; else ee3 = e3; - if(e4 == (char *)NULL) ee4 = ""; else ee4 = e4; - - /* XXX need to add locking mechanics to add new user */ - - if((fp = fopen(pwdfile, "a")) == (FILE *)NULL) - return(PASS_ERROR); - - fprintf(fp, "%s:%s:%s:%s:%s:%s\n", user, crypt(pass, sl), ee1, ee2, ee3, ee4); - - fclose(fp); - - /* XXX need to add unlocking mechanics to add new user */ - - return(PASS_GOOD); -} diff --git a/commands/httpd0995/pass.h b/commands/httpd0995/pass.h deleted file mode 100644 index 22a4e1dc8..000000000 --- a/commands/httpd0995/pass.h +++ /dev/null @@ -1,18 +0,0 @@ -/* pass.h - * - * This file is part of httpd. - * - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Initial Release Michael Temari - * - */ - -_PROTOTYPE(int passfile, (char *pwdfile)); -_PROTOTYPE(int passuser, (char *pwdfile, char *user)); -_PROTOTYPE(int passnone, (char *pwdfile, char *user)); -_PROTOTYPE(int passpass, (char *pwdfile, char *user, char *pass)); -_PROTOTYPE(int passadd, (char *pwdfile, char *user, char *pass, char *e1, char *e2, char *e3, char *e4)); - -#define PASS_GOOD 0 -#define PASS_USEREXISTS 1 -#define PASS_ERROR -1 diff --git a/commands/httpd0995/police.c b/commands/httpd0995/police.c deleted file mode 100644 index b71af8374..000000000 --- a/commands/httpd0995/police.c +++ /dev/null @@ -1,407 +0,0 @@ -/* police.c - * - * This file is part of httpd. - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "http.h" -#include "utility.h" -#include "config.h" -#include "pass.h" - -#define MATCH_NONE 0 -#define MATCH_WILD 1 -#define MATCH_FULL 2 - -_PROTOTYPE(static int authaccess, (struct http_request *rq, struct http_reply *rp)); -_PROTOTYPE(static void purl, (struct http_request *rq, struct http_reply *rp)); -_PROTOTYPE(static char *virt, (char *to, char *host)); - -static int authaccess(rq, rp) -struct http_request *rq; -struct http_reply *rp; -{ -struct auth *auth; -struct authuser *pu; - - /* set authorization to be checked against */ - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - auth = proxyauth; - else - auth = rp->auth; - - /* no authorization so no access to anyone */ - if(auth == NULL) { - rp->status = HTTP_STATUS_FORBIDDEN; - strcpy(rp->statusmsg, "No Authoriation"); - return(-1); - } - - /* access must be R for PROXY */ - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - if(!(auth->urlaccess & URLA_READ)) { - rp->status = HTTP_STATUS_FORBIDDEN; - strcpy(rp->statusmsg, "Proxy not authorized"); - return(-1); - } - - /* no password file so it is a free for all */ - if(auth->passwdfile == NULL) - return(0); - - /* they did not give us an authorized user */ - if(rq->authuser[0] == '\0') { - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - rp->status = HTTP_STATUS_PROXY_AUTH_REQRD; - else - rp->status = HTTP_STATUS_UNAUTHORIZED; - strcpy(rp->statusmsg, "No Authorized User Given"); - return(-1); - } - - /* check if user okay */ - pu = auth->users; - if(pu == NULL) - ; /* no user list we allow anyone in file */ - else { - while(pu != NULL) { - if(!strcmp(pu->user, rq->authuser)) - break; - pu = pu->next; - } - /* user is not in list so no access */ - if(pu == NULL) { - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - rp->status = HTTP_STATUS_PROXY_AUTH_REQRD; - else - rp->status = HTTP_STATUS_UNAUTHORIZED; - strcpy(rp->statusmsg, "Forbidden User not authorized"); - return(-1); - } - } - - /* check if password file exists, if not no access */ - if(passfile(auth->passwdfile)) { - rp->status = HTTP_STATUS_FORBIDDEN; - strcpy(rp->statusmsg, "Invalid passwd file"); - return(-1); - } - - /* check if user in password file, if not no access */ - if(passuser(auth->passwdfile, rq->authuser)) { - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - rp->status = HTTP_STATUS_PROXY_AUTH_REQRD; - else - rp->status = HTTP_STATUS_UNAUTHORIZED; - strcpy(rp->statusmsg, "Forbidden Bad User"); - return(-1); - } - - /* check if a password exists, if not no access */ - if(passnone(auth->passwdfile, rq->authuser)) { - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - rp->status = HTTP_STATUS_PROXY_AUTH_REQRD; - else - rp->status = HTTP_STATUS_UNAUTHORIZED; - strcpy(rp->statusmsg, "Forbidden no password"); - return(-1); - } - - /* check if password matches, if not no access */ - if(passpass(auth->passwdfile, rq->authuser, rq->authpass)) { - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - rp->status = HTTP_STATUS_PROXY_AUTH_REQRD; - else - rp->status = HTTP_STATUS_UNAUTHORIZED; - strcpy(rp->statusmsg, "Forbidden bad password"); - return(-1); - } - - /* whew, all the checks passed so I guess we let them have it */ - return(0); -} - -int police(rq, rp) -struct http_request *rq; -struct http_reply *rp; -{ -int size; -struct stat st; -struct dirsend *ds; - - purl(rq, rp); - - rp->mtype = "text/html"; - -#ifdef DEBUG - fprintf(stderr, "httpd: Trying %s\n", rp->realurl); -#endif - - /* now check authorizations */ - if(authaccess(rq, rp)) { - /* Don't give them any details why authorization failed */ - strcpy(rp->statusmsg, "No Access Granted"); - return(0); - } - - /* a proxy request only needs an authorization check */ - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - return(0); - - /* check access to real url */ - if(stat(rp->realurl, &st)) { - if(errno == EACCES) - rp->status = HTTP_STATUS_FORBIDDEN; - else - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - /* a PUT and NOT FOUND is okay since we are creating */ - if(rq->method != HTTP_METHOD_PUT || rp->status != HTTP_STATUS_NOT_FOUND) - return(0); - } - - /* If it is a directory do the appropriate thang! */ - if(rq->method == HTTP_METHOD_GET || rq->method == HTTP_METHOD_HEAD) - if((st.st_mode & S_IFMT) == S_IFDIR) { - if(rq->url[strlen(rq->url) - 1] != '/') { - strncat(rq->url, "/", sizeof(rq->url) - strlen(rq->url)); - rp->status = HTTP_STATUS_MOVED_TEMP; - sprintf(rp->statusmsg, "Moved to %s", rq->url); - return(0); - } - size = strlen(rq->url); - ds = dirsend; - while(ds != NULL) { - strncpy(rq->url+size, ds->file, sizeof(rq->url)-size); - purl(rq, rp); - if(stat(rp->realurl, &st)) { - if(errno == EACCES) - rp->status = HTTP_STATUS_FORBIDDEN; - else - if(errno != ENOENT) - rp->status = HTTP_STATUS_NOT_FOUND; - } else - break; - if(rp->status != HTTP_STATUS_OK) { - strcpy(rp->statusmsg, strerror(errno)); - return(0); - } - ds = ds->next; - } - if(ds == NULL) { - rq->url[size] = '\0'; - purl(rq, rp); - if(stat(rp->realurl, &st)) { - if(errno == EACCES) - rp->status = HTTP_STATUS_FORBIDDEN; - else - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - return(0); - } - } - } - - if(rq->method == HTTP_METHOD_PUT && !(rp->urlaccess & URLA_WRITE)) { - rp->status = HTTP_STATUS_METHOD_NOT_ALLOWED; - strcpy(rp->statusmsg, "Method not allowed"); - return(0); - } - - if(rp->status == HTTP_STATUS_OK) { - /* Here is where we check if it is a program or script to run */ - if(cgiexec(rq, rp)) - return(0); - - if((st.st_mode & S_IFMT) == S_IFDIR) { - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, "Directory listing not available"); - return(0); - } - - if((st.st_mode & S_IFMT) != S_IFREG) { - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, "Not a regular file"); - return(0); - } - } - - /* open the URL for updating */ - if(rq->method == HTTP_METHOD_PUT) { - rp->status = HTTP_STATUS_OK; - strcpy(rp->statusmsg, "OK"); - rp->ofd = open(rp->realurl, O_WRONLY | O_CREAT | O_TRUNC); - if(rp->ofd < 0) { - if(errno == EACCES) - rp->status = HTTP_STATUS_FORBIDDEN; - else - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - return(0); - } - return(0); - } - - if(!(rp->urlaccess & URLA_READ)) { - rp->status = HTTP_STATUS_FORBIDDEN; - strcpy(rp->statusmsg, "No way..."); - return(0); - } - - rp->mtype = mimetype(rp->realurl); - - rp->size = st.st_size; - rp->modtime = st.st_mtime; - - /* open the url if it is a file */ - rp->fd = open(rp->realurl, O_RDONLY); - if(rp->fd < 0) { - if(errno == EACCES) - rp->status = HTTP_STATUS_FORBIDDEN; - else - rp->status = HTTP_STATUS_NOT_FOUND; - strcpy(rp->statusmsg, strerror(errno)); - return(0); - } - - return(0); -} - -static void purl(rq, rp) -struct http_request *rq; -struct http_reply *rp; -{ -struct vpath *pv; -int gotreal, gotperm; -char *p; -int match; -int len; - - gotreal = 0; gotperm = 0; - -#ifdef DEBUG - fprintf(stderr, "httpd: Processing url = \"%s\"\n", rq->url); -#endif - - /* remove any .. references */ - p = rq->url; - while(*p) { - while(*p && *p != '/') p++; - if(*p != '/') continue; - p++; - if(*p != '.') continue; - p++; - if(*p != '.') continue; - p++; - strcpy(p - 3, p); - p = p - 3; - } - - for(pv = vpath; pv != NULL; pv = pv->next) { - len = strlen(pv->from) - 1; - if(pv->from[len] == '*' || pv->from[len] == '$') - if(len == 0) - match = MATCH_WILD; - else - match = strncmp(rq->url, pv->from, len) ? MATCH_NONE : MATCH_WILD; - else - if(!strcmp(rq->url, pv->from)) - match = MATCH_FULL; - else - match = MATCH_NONE; -#ifdef DEBUG - fprintf(stderr, "httpd: Trying \"%s\" %d %d %d %s\n", - pv->from, match, gotreal, gotperm, pv->auth->name); -#endif - if(match != MATCH_NONE) { - gotperm = 1; - rp->auth = pv->auth; - if(pv->urlaccess == -1 && rp->auth != NULL) - rp->urlaccess = rp->auth->urlaccess; - else - rp->urlaccess = pv->urlaccess; - if(strcmp(pv->to, ".")) { - gotreal = 1; - strncpy(rp->realurl, virt(pv->to, rq->host), sizeof(rp->realurl)); - rp->realurl[sizeof(rp->realurl)-1] = '\0'; - if(match == MATCH_WILD && pv->from[len] != '$') { - strncat(rp->realurl, rq->url+len, sizeof(rp->realurl) - strlen(rp->realurl)); - rp->realurl[sizeof(rp->realurl)-1] = '\0'; - } - } - } - if(match == MATCH_FULL) break; - } - - if(rp->urlaccess == -1) rp->urlaccess = mkurlaccess(""); - - if(!gotreal) { - strncpy(rp->realurl, rq->url, sizeof(rp->realurl)); - rp->realurl[sizeof(rp->realurl)-1] = '\0'; - } - - if(!gotperm) - rp->auth = NULL; - -#ifdef DEBUG - fprintf(stderr, "DEBUG: url = \"%s\" realurl = \"%s\" auth = \"%s\"\n", - rq->url, rp->realurl, ((rp->auth == NULL) ? "No Access" : rp->auth->name)); - fprintf(stderr, "DEBUG: query = %s\n", rq->query); -#endif - - return; -} - -static char *virt(to, host) -char *to; -char *host; -{ -static char vroot[256]; -struct vhost *ph; - -#ifdef DEBUG -fprintf(stderr, "virt: %s %s\n", to, host); -#endif - - if(vhost == NULL) return(to); - - if(to[0] != '/') return(to); - if(to[1] != '/') return(to); - if(to[2] != '/') return(to); - - vroot[0] = '\0'; - - for(ph = vhost; ph != NULL; ph = ph->next) { -#ifdef DEBUG - fprintf(stderr, "ph: %s %s %s\n", ph->hname, ph->root, vroot); -#endif - if(!strcmp(ph->hname, "*") && vroot[0] == '\0') - strncpy(vroot, ph->root, sizeof(vroot)); - if(!strcasecmp(ph->hname, host)) { - strncpy(vroot, ph->root, sizeof(vroot)); - break; - } - } - - strncat(vroot, to+3, sizeof(vroot)); - -#ifdef DEBUG - fprintf(stderr, "vroot: %s\n", vroot); -#endif - - return(vroot); -} diff --git a/commands/httpd0995/process.c b/commands/httpd0995/process.c deleted file mode 100644 index 665fc70a8..000000000 --- a/commands/httpd0995/process.c +++ /dev/null @@ -1,90 +0,0 @@ -/* process.c - * - * This file is part of httpd. - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Relase Michael Temari - * 12/29/2002 Michael Temari - * 05/14/2006 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "http.h" -#include "utility.h" - -int processrequest(rq, rp) -struct http_request *rq; -struct http_reply *rp; -{ - /* clear out http_reply */ - memset(rp, 0, sizeof(*rp)); - rp->status = HTTP_STATUS_OK; - strcpy(rp->statusmsg, "OK"); - rp->modtime = (time_t) -1; - rp->urlaccess = -1; - rp->size = 0; - rp->fd = -1; - rp->ofd = -1; - rp->pid = 0; - - if(Redirect != NULL) { - rp->status = HTTP_STATUS_MOVED_PERM; - strcpy(rp->realurl, Redirect); - strcat(rp->realurl, rq->uri); - strcpy(rq->url, rp->realurl); - return(0); - } - - /* Simple requests can only be a GET */ - if(rq->type == HTTP_REQUEST_TYPE_SIMPLE && rq->method != HTTP_METHOD_GET) { - rp->status = HTTP_STATUS_BAD_REQUEST; - strcpy(rp->statusmsg, "Bad request"); - return(0); - } - - /* I don't know this method */ - if(rq->method == HTTP_METHOD_UNKNOWN) { - rp->status = HTTP_STATUS_NOT_IMPLEMENTED; - strcpy(rp->statusmsg, "Method not implemented"); - return(0); - } - - /* Check for access and real location of url */ - if(police(rq, rp)) - return(-1); - - /* We're done if there was an error accessing the url */ - if(rp->status != HTTP_STATUS_OK) - return(0); - - /* Check to see if we have a newer version for them */ - if(rq->method == HTTP_METHOD_GET) - if(rq->ifmodsince != (time_t) -1) - if(rq->ifmodsince < time((time_t *)NULL)) - if(rp->modtime != (time_t) -1 && rp->modtime <= rq->ifmodsince) { - rp->status = HTTP_STATUS_NOT_MODIFIED; - strcpy(rp->statusmsg, "Not modified"); - close(rp->fd); - rp->fd = -1; - return(0); - } - - rp->status = HTTP_STATUS_OK; - strcpy(rp->statusmsg, "OK"); - - if(rp->size != 0) - rp->keepopen = rq->keepopen; - - return(0); -} diff --git a/commands/httpd0995/proxy.c b/commands/httpd0995/proxy.c deleted file mode 100644 index d93acee9e..000000000 --- a/commands/httpd0995/proxy.c +++ /dev/null @@ -1,292 +0,0 @@ -/* proxy.c Copyright 2000 by Michael Temari All Rights Reserved */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "config.h" -#include "http.h" -#include "utility.h" -#include "net.h" - -_PROTOTYPE(static int connect, (char *host)); -#if 0 -_PROTOTYPE(static int readline, (char *p, int len)); -#endif -_PROTOTYPE(static int sendout, (int fd, char *data)); - -static int connect(host) -char *host; -{ -nwio_tcpconf_t tcpconf; -nwio_tcpcl_t tcpcopt; -char *tcp_device; -int netfd; -ipaddr_t nethost; -tcpport_t netport = 0; -struct hostent *hp; -struct servent *sp; -char *p; -int s; -int tries; - - p = host; - while(*p && *p != ':') p++; - if(*p == ':') { - *p++ = '\0'; - netport = htons(atoi(p)); - } - - if((hp = gethostbyname(host)) == (struct hostent *)NULL) { - fprintf(stderr, "Unknown host %s!\n", host); - return(-1); - } else - memcpy((char *) &nethost, (char *) hp->h_addr, hp->h_length); - - /* Now, to which port must we connect? */ - if(netport == 0) - if((sp = getservbyname("http", "tcp")) == (struct servent *)NULL) { - fprintf(stderr, "HTTP port is unknown????\n"); - return(-1); - } else - netport = sp->s_port; - - /* Connect to the host */ - if((tcp_device = getenv("TCP_DEVICE")) == NULL) - tcp_device = TCP_DEVICE; - - if((netfd = open(tcp_device, O_RDWR)) < 0) { - perror("httpget: opening tcp"); - return(-1); - } - - tcpconf.nwtc_flags = NWTC_LP_SEL | NWTC_SET_RA | NWTC_SET_RP; - tcpconf.nwtc_remaddr = nethost; - tcpconf.nwtc_remport = netport; - - s = ioctl(netfd, NWIOSTCPCONF, &tcpconf); - if(s < 0) { - perror("httpget: NWIOSTCPCONF"); - close(netfd); - return(-1); - } - - s = ioctl(netfd, NWIOGTCPCONF, &tcpconf); - if(s < 0) { - perror("httpget: NWIOGTCPCONF"); - close(netfd); - return(-1); - } - - tcpcopt.nwtcl_flags = 0; - - tries = 0; - do { - s = ioctl(netfd, NWIOTCPCONN, &tcpcopt); - if(s == -1 && errno == EAGAIN) { - if(tries++ >= 10) - break; - sleep(10); - } else - break; - } while(1); - - if(s < 0) { - perror("httpget: NWIOTCPCONN"); - close(netfd); - return(-1); - } - - return(netfd); -} - -char buffer[8192]; - -#if 0 -static int readline(p, len) -char *p; -int len; -{ -int c; -int cr = 0; -int n = 0; - - len--; - if(len < 0) return(-1); - while(len > 0 && (c = getchar()) != EOF) { - if(c == '\n' && cr) { - *p = '\0'; - return(n); - } - if(c == '\r') { - cr = 1; - continue; - } - n++; - *p++ = c; - } - *p = '\0'; - return(n); -} -#endif - -static int sendout(fd, data) -int fd; -char *data; -{ - if(strlen(data) > 0) - write(fd, data, strlen(data)); - write(fd, "\r\n", 2); - if(dbglog != (FILE *)NULL) { - fprintf(dbglog, "REPLY: %s\n", data); - fflush(dbglog); - } - - return(0); -} - -void proxy(rq, rp) -struct http_request *rq; -struct http_reply *rp; -{ -int s; -char *p; -char *ps; -char *b; -char *host; -static char user[256]; -static char pass[256]; -char *url; -char *at; -int fd; -int bad; - - while(1) { - bad = 0; - p = rq->uri; - if(tolower(*p++) != 'h') bad++; - if(tolower(*p++) != 't') bad++; - if(tolower(*p++) != 't') bad++; - if(tolower(*p++) != 'p') bad++; - if(tolower(*p++) != ':') bad++; - if(tolower(*p++) != '/') bad++; - if(tolower(*p++) != '/') bad++; - if(bad) { - sprintf(buffer, "HTTP/%d.%d 400 Bad Request", - rq->vmajor, rq->vminor); - sendout(1, buffer); - sendout(1, ""); - sendout(1, "Proxy Request was not http:"); - return; - } - host = p; - while(*p && *p != '/') p++; - url = p; - *url = '\0'; - at = strchr(host, '@'); - if(at != (char *)NULL) { - *at = '\0'; - p = host; - while(*p && *p != ':') p++; - if(*p) - *p++ = '\0'; - strcpy(user, host); - strcpy(pass, p); - host = at + 1; - } else { - user[0] = '\0'; - pass[0] = '\0'; - } - - fd = connect(host); - if(fd < 0) { - sprintf(buffer, "HTTP/%d.%d 400 Bad Request", - rq->vmajor, rq->vminor); - sendout(1, buffer); - sendout(1, ""); - sendout(1, "Could not connect to host"); - return; - } - if(rq->method == HTTP_METHOD_GET) - write(fd, "GET ", 4); else - if(rq->method == HTTP_METHOD_POST) - write(fd, "POST ", 5); - *url = '/'; - if(strlen(url) > 0) - write(fd, url, strlen(url)); - write(fd, " ", 1); - sprintf(buffer, "HTTP/%d.%d", rq->vmajor, rq->vminor); - sendout(fd, buffer); - if(rq->ifmodsince != -1) { - write(fd, "If-Mod-Since: ", 14); - sendout(fd, httpdate(&rq->ifmodsince)); - } - if(rq->size != 0) { - sendout(fd, "Content-Type: application/x-www-form-urlencoded"); - sprintf(buffer, "Content-Length: %lu", rq->size); - sendout(fd, buffer); - } - if(*rq->cookie) { - sprintf(buffer, "Cookie: %s", rq->cookie); - sendout(fd, buffer); - } - if(*rq->useragent) { - sprintf(buffer, "User-Agent: %s", rq->useragent); - sendout(fd, buffer); - } - if(*rq->host) { - sprintf(buffer, "Host: %s", rq->host); - sendout(fd, buffer); - } - if(*rq->wwwauth) { - sprintf(buffer, "Authorization: %s", rq->wwwauth); - sendout(fd, buffer); - } - sprintf(buffer, "X-Forwarded-From: %s", rmthostaddr); - sendout(fd, buffer); - sendout(fd, ""); - if(rq->size != 0) { - if(stdlog != (FILE *)NULL) { - fprintf(stdlog, "%s %s %d %d ", - logdate((time_t *)NULL), rmthostname, - rq->method, rp->status); - fprintf(stdlog, "proxy %s?", rq->uri); - } - while((s = read(0, buffer, rq->size > - sizeof(buffer) ? sizeof(buffer) : rq->size)) > 0) { - write(fd, buffer, s); - rq->size -= s; - b = buffer; - if(stdlog != (FILE *)NULL) - while(s--) fputc(*b++, stdlog); - if(rq->size == 0) break; - } - if(stdlog != (FILE *)NULL) { - fprintf(stdlog, "\n"); - fflush(stdlog); - } - } - while((s = read(fd, buffer, sizeof(buffer))) > 0) { - write(1, buffer, s); - } - close(fd); - return; - } -} diff --git a/commands/httpd0995/reply.c b/commands/httpd0995/reply.c deleted file mode 100644 index ba46535b6..000000000 --- a/commands/httpd0995/reply.c +++ /dev/null @@ -1,189 +0,0 @@ -/* reply.c - * - * This file is part of httpd. - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include - -#include "http.h" -#include "utility.h" -#include "net.h" -#include "config.h" - -#define SERVER "Server: "VERSION - -_PROTOTYPE(static void GotAlarm, (int sig)); -_PROTOTYPE(static int sendout, (char *data)); - -static void GotAlarm(sig) -int sig; -{ -} - -static int sendout(data) -char *data; -{ - if(strlen(data) > 0) - write(1, data, strlen(data)); - write(1, "\r\n", 2); - if(dbglog != (FILE *)NULL) { - fprintf(dbglog, "REPLY: %s\n", data); - fflush(dbglog); - } - - return(0); -} - -int sendreply(rp, rq) -struct http_reply *rp; -struct http_request *rq; -{ -int s; -int s2; -int e; -static char buffer[8192]; - - if(rq->type != HTTP_REQUEST_TYPE_PROXY) - /* We're receiving data from a */ - if(rq->method == HTTP_METHOD_POST || - (rq->method == HTTP_METHOD_PUT && rp->status == HTTP_STATUS_OK)) { - if(rq->type != HTTP_REQUEST_TYPE_FULL) - return(0); - if(rq->method == HTTP_METHOD_PUT) - rp->status = HTTP_STATUS_CREATED; - else - rp->status = HTTP_STATUS_OK; - while(rq->size != 0) { - s = read(0, buffer, (rq->size > sizeof(buffer)) ? sizeof(buffer) : rq->size); - if(s <= 0) { - rp->status = HTTP_STATUS_SERVER_ERROR; - strcpy(rp->statusmsg, strerror(errno)); - close(rp->fd); - close(rp->ofd); - break; - } - rq->size -= s; - s2 = write(rp->ofd, buffer, s); - if(s2 != s) break; - } - } - - if(rp->status != HTTP_STATUS_OK && rp->status != HTTP_STATUS_CREATED && - rp->status != HTTP_STATUS_NOT_MODIFIED) - rp->keepopen = 0; - - if(rp->status == HTTP_STATUS_NOT_MODIFIED) { - sprintf(buffer, "

Error %03d %s

", - rp->status, rp->statusmsg); - rp->size = strlen(buffer); - rp->keepopen = rq->keepopen; - } - - if(!rp->headers) { - - if((rq->type == HTTP_REQUEST_TYPE_PROXY && rp->status != HTTP_STATUS_OK) || - rq->type == HTTP_REQUEST_TYPE_FULL) { - sprintf(buffer, "HTTP/%d.%d %03d %s", - rq->vmajor, rq->vminor, rp->status, rp->statusmsg); - sendout(buffer); - sendout(SERVER); - if(rp->status == HTTP_STATUS_MOVED_PERM || - rp->status == HTTP_STATUS_MOVED_TEMP) { -#if 1 - sprintf(buffer, "Location: %s", rq->url); -#else - sprintf(buffer, "Location: http://%s%s", myhostname, rq->url); -#endif - sendout(buffer); - } - if(rp->keepopen) - sendout("Connection: Keep-Alive"); - else - sendout("Connection: Close"); - if(rp->status == HTTP_STATUS_UNAUTHORIZED && rp->auth != NULL) { - sprintf(buffer, "WWW-Authenticate: Basic realm=\"%s\"", rp->auth->desc); - sendout(buffer); - } - if(rp->status == HTTP_STATUS_PROXY_AUTH_REQRD && proxyauth != NULL) { - sprintf(buffer, "Proxy-Authenticate: Basic realm=\"%s\"", proxyauth->desc); - sendout(buffer); - } - if(rp->modtime != (time_t) -1) { - sprintf(buffer, "Last-Modified: %s", httpdate(&rp->modtime)); - sendout(buffer); - } - if(rp->size != 0) { - sprintf(buffer, "Content-Length: %lu", rp->size); - sendout(buffer); - } - if(rp->status == HTTP_STATUS_OK) { - sprintf(buffer, "Content-Type: %s", rp->mtype); - sendout(buffer); - } else - sendout("Content-Type: text/html"); - if(!rp->headers) - sendout(""); - } else - if(rp->status != HTTP_STATUS_OK) - return(0); - } - - if(rp->status != HTTP_STATUS_OK && rp->status != HTTP_STATUS_CREATED) { - sprintf(buffer, "

Error %03d %s

", - rp->status, rp->statusmsg); - sendout(buffer); - return(0); - } - - if(rq->type == HTTP_REQUEST_TYPE_PROXY) { - proxy(rq, rp); - return(0); - } - - /* send out entity body */ - if(rq->method == HTTP_METHOD_GET || rq->method == HTTP_METHOD_POST) { - errno = 0; - while(1) { - alarm(0); - signal(SIGALRM, GotAlarm); - alarm(10); - s = read(rp->fd, buffer, sizeof(buffer)); - e = errno; - alarm(0); - if(s > 0) { - s2 = write(1, buffer, s); - e = errno; - if(s2 != s) break; - continue; - } - if(s == 0) break; - if(s < 0 && e != EINTR) break; - signal(SIGALRM, GotAlarm); - alarm(2); - s = read(0, buffer, 1); - e = errno; - alarm(0); - if(s < 0 && e != EINTR) break; - } - } - - close(rp->fd); - rp->fd = -1; - if(rp->ofd != -1) - close(rp->ofd); - if(rp->pid != 0 && e != 0) { - kill(-rp->pid, SIGHUP); - rp->pid = 0; - } - - return(0); -} diff --git a/commands/httpd0995/request.c b/commands/httpd0995/request.c deleted file mode 100644 index 2b5b36a4f..000000000 --- a/commands/httpd0995/request.c +++ /dev/null @@ -1,369 +0,0 @@ -/* request.c - * - * This file is part of httpd. - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef _MINIX -#include -#endif -#include - -#include "http.h" -#include "utility.h" -#include "config.h" - -_PROTOTYPE(static void Timeout, (int sig)); -_PROTOTYPE(static int getline, (char *buffer, int size)); -_PROTOTYPE(static void authorize, (char *p, struct http_request *rq)); -_PROTOTYPE(static void decurl, (char *u)); - -static int TimeOut; - -static void Timeout(sig) -int sig; -{ - TimeOut = 1; -} - -static int getline(buffer, size) -char *buffer; -int size; -{ -char *p; -int s; - - p = buffer; - - while(p < (buffer + size - 1)) { - TimeOut = 0; - signal(SIGALRM, Timeout); - alarm(5*60); - s = read(0, p, 1); - alarm(0); - if(TimeOut) - return(-1); - if(s != 1) - return(-1); - if(*p == '\n') break; - p++; - } - *++p = '\0'; - - p = &buffer[strlen(buffer) - 1]; - if(p >= buffer && (*p == '\r' || *p == '\n')) *p-- ='\0'; - if(p >= buffer && (*p == '\r' || *p == '\n')) *p-- ='\0'; - - return(strlen(buffer)); -} - -static void authorize(p, rq) -char *p; -struct http_request *rq; -{ -char *s; - - if(toupper(*p++) == 'B' && - toupper(*p++) == 'A' && - toupper(*p++) == 'S' && - toupper(*p++) == 'I' && - toupper(*p++) == 'C' && - toupper(*p++) == ' ') ; - else - return; - - s = decode64(p); - - if((p = strchr(s, ':')) == (char *)NULL) - p = ""; - else - *p++ = '\0'; - - strncpy(rq->authuser, s, sizeof(rq->authuser)); - strncpy(rq->authpass, p, sizeof(rq->authpass)); - - return; -} - -int getrequest(rq) -struct http_request *rq; -{ -static char line[4096]; -char *p, *p2, *ps; -int s, len; -struct vhost *ph; - - /* get request, it may be simple */ - - s = getline(line, sizeof(line)); - if(s < 0) - return(-1); - - if(dbglog != (FILE *)NULL) { - fprintf(dbglog, "REQUEST: %s\n", line); - fflush(dbglog); - } - - /* clear http_request */ - memset(rq, 0, sizeof(*rq)); - rq->ifmodsince = (time_t) -1; - - /* assume simple request */ - rq->type = HTTP_REQUEST_TYPE_SIMPLE; - - /* parse the method */ - p = line; - while(*p && !LWS(*p)) { - *p = toupper(*p); - p++; - } - if(*p) *p++ = '\0'; - - if(!strcmp(line, "GET")) - rq->method = HTTP_METHOD_GET; else - if(!strcmp(line, "HEAD")) - rq->method = HTTP_METHOD_HEAD; else - if(!strcmp(line, "POST")) - rq->method = HTTP_METHOD_POST; else - if(!strcmp(line, "PUT")) - rq->method = HTTP_METHOD_PUT; else -#if 0 - if(!strcmp(line, "OPTIONS")) - rq->method = HTTP_METHOD_OPTIONS; else - if(!strcmp(line, "PATCH")) - rq->method = HTTP_METHOD_PATCH; else - if(!strcmp(line, "COPY")) - rq->method = HTTP_METHOD_COPY; else - if(!strcmp(line, "MOVE")) - rq->method = HTTP_METHOD_MOVE; else - if(!strcmp(line, "DELETE")) - rq->method = HTTP_METHOD_DELETE; else - if(!strcmp(line, "LINK")) - rq->method = HTTP_METHOD_LINK; else - if(!strcmp(line, "UNLINK")) - rq->method = HTTP_METHOD_UNLINK; else - if(!strcmp(line, "TRACE")) - rq->method = HTTP_METHOD_TRACE; else - if(!strcmp(line, "WRAPPED")) - rq->method = HTTP_METHOD_WRAPPED; else -#endif - rq->method = HTTP_METHOD_UNKNOWN; - - /* parse the requested URI */ - p2 = rq->uri; - len = sizeof(rq->uri) - 1; - while(*p && !LWS(*p) && len > 0) { - *p2++ = *p++; - len--; - } - *p2 = '\0'; - - /* eat up any leftovers if uri was too big */ - while(*p && !LWS(*p)) - p++; - - /* save for continued processing later */ - ps = p; - - /* parse the requested URL */ - p = rq->uri; - p2 = rq->url; - len = sizeof(rq->url) - 1; - while(*p && !LWS(*p) && *p != '?' && len > 0) { - *p2++ = *p++; - len--; - } - *p2 = '\0'; - - /* See if there is a query string */ - if(*p == '?') { - p++; - p2 = rq->query; - len = sizeof(rq->query) - 1; - while(*p && !LWS(*p) && len > 0) { - *p2++ = *p++; - len--; - } - } - - /* eat up any leftovers */ - while(*p && !LWS(*p)) p++; - - if(rq->url[0] == '\0') { - rq->url[0] = '/'; - rq->url[1] = '\0'; - } - - /* url is a decoded copy of the uri */ - decurl(rq->url); - - /* restore and continue processing */ - p = ps; - - /* if this is true it is a simple request */ - if(*p == '\0') - return(0); - - /* parse HTTP version */ - while(*p && LWS(*p)) p++; - if(toupper(*p++) != 'H') return(0); - if(toupper(*p++) != 'T') return(0); - if(toupper(*p++) != 'T') return(0); - if(toupper(*p++) != 'P') return(0); - if( *p++ != '/') return(0); - - /* version major */ - rq->vmajor = 0; - while((*p >= '0') && (*p <= '9')) - rq->vmajor = rq->vmajor * 10 + (*p++ - '0'); - if(*p != '.') - return(0); - p++; - - /* version minor */ - rq->vminor = 0; - while((*p >= '0') && (*p <= '9')) - rq->vminor = rq->vminor * 10 + (*p++ - '0'); - if(*p) - return(0); - - rq->type = HTTP_REQUEST_TYPE_FULL; - - p = rq->uri; - - /* check if it is a proxy request */ - if(toupper(*p++) == 'H' && - toupper(*p++) == 'T' && - toupper(*p++) == 'T' && - toupper(*p++) == 'P' && - toupper(*p++) == ':') - rq->type = HTTP_REQUEST_TYPE_PROXY; - - /* parse any header fields */ - while((s = getline(line, sizeof(line))) > 0) { - if(toupper(line[0]) == 'A' && - toupper(line[1]) == 'U') - if(dbglog != (FILE *)NULL) { - fprintf(dbglog, "REQUEST: Authorization:\n"); - fflush(dbglog); - } else ; - else - if(dbglog != (FILE *)NULL) { - fprintf(dbglog, "REQUEST: %s\n", line); - fflush(dbglog); - } - p = line; - while(*p && *p != ':') { - *p = toupper(*p); - p++; - } - if(*p != ':') continue; /* bad header field, skip it */ - *p++ = '\0'; - while(*p && LWS(*p)) p++; - - /* header field value parsing here */ - if(!strcmp(line, "HOST")) { - strncpy(rq->host, p, sizeof(rq->host)); - p2 = strrchr(rq->host, ':'); - if(p2 != (char *)NULL) { - *p2++ = '\0'; - rq->port = atoi(p2); - } - /* if unknown virtual host then exit quietly */ - for(ph = vhost; ph != NULL; ph = ph->next) { - if(!strcasecmp(ph->hname, "*")) break; - if(!strcasecmp(ph->hname, rq->host)) break; - } - if(rq->type != HTTP_REQUEST_TYPE_PROXY) - if(ph == NULL && vhost != NULL) return(1); - } else - if(!strcmp(line, "USER-AGENT")) - strncpy(rq->useragent, p, sizeof(rq->useragent)); else - if(!strcmp(line, "CONNECTION")) - rq->keepopen = strcasecmp(p, "Keep-Alive") ? 0 : 1; else - if(!strcmp(line, "IF-MODIFIED-SINCE")) - rq->ifmodsince = httptime(p); else - if(!strcmp(line, "CONTENT-LENGTH")) - rq->size = atol(p); else - if(!strcmp(line, "AUTHORIZATION")) { - strncpy(rq->wwwauth, p, sizeof(rq->wwwauth)); - if(rq->type != HTTP_REQUEST_TYPE_PROXY) - authorize(p, rq); - } else - if(!strcmp(line, "PROXY-AUTHORIZATION")) { - if(rq->type == HTTP_REQUEST_TYPE_PROXY) - authorize(p, rq); - } else - if(!strcmp(line, "DATE")) - rq->msgdate = httptime(p); else - if(!strcmp(line, "COOKIE")) { - strncpy(rq->cookie, p, sizeof(rq->cookie)-1); - rq->cookie[sizeof(rq->cookie)-1] = '\0'; - } - } - - if(rq->type != HTTP_REQUEST_TYPE_PROXY) - if(*rq->host == '\0' && vhost != NULL) return(1); - - if(dbglog != (FILE *)NULL && rq->authuser[0] != '\0') { - fprintf(dbglog, "REQUEST: AuthUser=%s\n", rq->authuser); - fflush(dbglog); - } - - if(s < 0) { - fprintf(stderr, "httpd: getrequest: Error getline (header fields)\n"); - return(-1); - } - - return(0); -} - -static void decurl(u) -char *u; -{ -char *p; -char h1, h2; -char c; - - p = u; - while(*p) { - switch(*p) { - case '\0': - c = '\0'; - break; - case '+': - c = ' '; - p++; - break; - case '%': - h1 = '0'; - h2 = '0'; - p++; - h1 = tolower(*p); - if(*p) p++; - h2 = tolower(*p); - if(*p) p++; - c = (h1 > '9') ? (10 + h1 - 'a') : (h1 - '0'); - c = 16 * c + ((h2 > '9') ? (10 + h2 - 'a') : (h2 - '0')); - break; - default: - c = *p++; - } - *u++ = c; - } - *u = '\0'; -} diff --git a/commands/httpd0995/utility.c b/commands/httpd0995/utility.c deleted file mode 100644 index 543a9d053..000000000 --- a/commands/httpd0995/utility.c +++ /dev/null @@ -1,265 +0,0 @@ -/* utility.c - * - * This file is part of httpd - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Initial Release Michael Temari - * - */ -#include -#include -#include -#include -#include -#include - -#include "utility.h" -#include "config.h" - -const char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }; -const char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - -char *logdate(t) -time_t *t; -{ -time_t worktime; -struct tm *tm; -static char datebuffer[80]; - - if(t == (time_t *)NULL) - (void) time(&worktime); - else - worktime = *t; - - tm = localtime(&worktime); - - sprintf(datebuffer, "%4d%02d%02d%02d%02d%02d", - 1900+tm->tm_year, - tm->tm_mon + 1, - tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec); - - return(datebuffer); -} - -char *httpdate(t) -time_t *t; -{ -time_t worktime; -struct tm *tm; -static char datebuffer[80]; - - if(t == (time_t *)NULL) - (void) time(&worktime); - else - worktime = *t; - - tm = gmtime(&worktime); - - sprintf(datebuffer, "%s, %02d %s %4d %02d:%02d:%02d GMT", - days[tm->tm_wday], - tm->tm_mday, months[tm->tm_mon], 1900+tm->tm_year, - tm->tm_hour, tm->tm_min, tm->tm_sec); - - return(datebuffer); -} - -time_t httptime(p) -char *p; -{ -time_t worktime, gtime, ltime; -struct tm tm; -struct tm *tm2; -int i; - - worktime = (time_t) -1; - - tm.tm_yday = 0; - tm.tm_isdst = -1; - - /* day of week */ - for(i = 0; i < 7; i++) - if(!strncmp(p, days[i], 3)) break; - if(i < 7) - tm.tm_wday = i; - else - return(worktime); - while(*p && *p != ' ') p++; - if(!*p) return(worktime); - while(*p && *p == ' ') p++; - if(!*p) return(worktime); - - if(*p >= '0' && *p <= '9') { - /* day */ - if(*(p+1) >= '0' && *(p+1) <= '9') - tm.tm_mday = 10 * (*p - '0') + (*(p+1) - '0'); - else - return(worktime); - p += 3; - /* month */ - for(i = 0; i < 12; i++) - if(!strncmp(p, months[i], 3)) break; - if(i < 12) - tm.tm_mon = i; - else - return(worktime); - p += 3; - if(!*p++) return(worktime); - /* year */ - tm.tm_year = atoi(p); - while(*p && *p != ' ') p++; - if(*p) p++; - } else { - /* day */ - tm.tm_mday = atoi(p); - while(*p && *p != ' ') p++; - while(*p && *p == ' ') p++; - if(!*p) return(worktime); - } - - /* hour */ - if(*p < '0' || *p > '9' || *(p+1) < '0' || *(p+1) > '9' || *(p+2) != ':') return(worktime); - tm.tm_hour = 10 * (*p - '0') + (*(p+1) - '0'); - p += 3; - - /* minute */ - if(*p < '0' || *p > '9' || *(p+1) < '0' || *(p+1) > '9' || *(p+2) != ':') return(worktime); - tm.tm_min = 10 * (*p - '0') + (*(p+1) - '0'); - p += 3; - - /* second */ - if(*p < '0' || *p > '9' || *(p+1) < '0' || *(p+1) > '9' || *(p+2) != ' ') return(worktime); - tm.tm_sec = 10 * (*p - '0') + (*(p+1) - '0'); - p += 3; - while(*p && *p == ' ') p++; - if(!*p) return(worktime); - - if(*p >= '0' && *p <= '9') - tm.tm_year = atoi(p); - else - if(*p++ != 'G' || *p++ != 'M' || *p++ != 'T') - return(worktime); - - if(tm.tm_year == 0) - return(worktime); - - if(tm.tm_year > 1900) - tm.tm_year -= 1900; - - worktime = mktime(&tm); - - gtime = mktime(gmtime(&worktime)); - tm2 = localtime(&worktime); - tm2->tm_isdst = 0; - ltime = mktime(tm2); - - worktime = worktime - (gtime - ltime); - - return(worktime); -} - -char *mimetype(url) -char *url; -{ -char *p; -struct msufx *ps; -char *dmt; - - dmt = (char *) NULL; - p = url; - while(*p) { - if(*p != '.') { - p++; - continue; - } - for(ps = msufx; ps != NULL; ps = ps->snext) - if(!strcmp(ps->suffix, "") && dmt == (char *) NULL) - dmt = ps->mtype->mimetype; - else - if(!strcmp(p, ps->suffix)) - return(ps->mtype->mimetype); - p++; - } - - if(dmt == (char *) NULL) - dmt = "application/octet-stream"; - - return(dmt); -} - -char *decode64(p) -char *p; -{ -static char decode[80]; -char c[4]; -int i; -int d; - - i = 0; - d = 0; - - while(*p) { - if(*p >= 'A' && *p <= 'Z') c[i++] = *p++ - 'A'; else - if(*p >= 'a' && *p <= 'z') c[i++] = *p++ - 'a' + 26; else - if(*p >= '0' && *p <= '9') c[i++] = *p++ - '0' + 52; else - if(*p == '+') c[i++] = *p++ - '+' + 62; else - if(*p == '/') c[i++] = *p++ - '/' + 63; else - if(*p == '=') c[i++] = *p++ - '='; else - return(""); - if(i < 4) continue; - decode[d++] = ((c[0] << 2) | (c[1] >> 4)); - decode[d++] = ((c[1] << 4) | (c[2] >> 2)); - decode[d++] = ((c[2] << 6) | c[3]); - decode[d] = '\0'; - i = 0; - } - - return(decode); -} - -int getparms(p, parms, maxparms) -char *p; -char *parms[]; -int maxparms; -{ -int np; - - np = 0; - - if(LWS(*p)) { - while(*p && LWS(*p)) p++; - if(!*p) return(0); - parms[np++] = (char *)NULL; - } else - np = 0; - - while(np < maxparms && *p) { - parms[np++] = p; - while(*p && !LWS(*p)) p++; - if(*p) *p++ = '\0'; - while(*p && LWS(*p)) p++; - } - - return(np); -} - -int mkurlaccess(p) -char *p; -{ -int ua; - - ua = 0; - - while(*p) { - if(toupper(*p) == 'R') ua |= URLA_READ; else - if(toupper(*p) == 'W') ua |= URLA_WRITE; else - if(toupper(*p) == 'X') ua |= URLA_EXEC; else - if(toupper(*p) == 'H') ua |= URLA_HEADERS; else - return(0); - p++; - } - - return(ua); -} diff --git a/commands/httpd0995/utility.h b/commands/httpd0995/utility.h deleted file mode 100644 index a66160ead..000000000 --- a/commands/httpd0995/utility.h +++ /dev/null @@ -1,19 +0,0 @@ -/* utility.h - * - * This file is part of httpd. - * - * 02/17/1996 Michael Temari - * 07/07/1996 Initial Release Michael Temari - * 12/29/2002 Michael Temari - * - */ - -#define LWS(c) ((c == ' ') || (c == '\t') || (c == '\r') || (c == '\n')) - -_PROTOTYPE(char *logdate, (time_t *t)); -_PROTOTYPE(char *httpdate, (time_t *t)); -_PROTOTYPE(time_t httptime, (char *p)); -_PROTOTYPE(char *mimetype, (char *url)); -_PROTOTYPE(char *decode64, (char *p)); -_PROTOTYPE(int getparms, (char *p, char *parms[], int maxparms)); -_PROTOTYPE(int mkurlaccess, (char *p)); diff --git a/commands/i86/Makefile b/commands/i86/Makefile deleted file mode 100644 index cfec0ed0c..000000000 --- a/commands/i86/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Makefile for commands/i86. - -CFLAGS = -D_MINIX -D_POSIX_SOURCE -CCLD = $(CC) -i $(CFLAGS) -MAKE = exec make -$(MAKEFLAGS) -CC = exec cc - -all: cc - -cc: cc.c - $(CCLD) -o $@ $? - install -S 6kb $@ - -install: /usr/bin/cc - -/usr/bin/cc: cc - install -cs -o bin $? $@ - -clean: - rm -rf a.out core cc diff --git a/commands/i86/cc.c b/commands/i86/cc.c deleted file mode 100644 index f753232db..000000000 --- a/commands/i86/cc.c +++ /dev/null @@ -1,1059 +0,0 @@ -/* Driver for Minix compilers. - Written june 1987 by Ceriel J.H. Jacobs, partly derived from old - cc-driver, written by Erik Baalbergen. - This driver is mostly table-driven, the table being in the form of - some global initialized structures. -*/ -/* $Header$ */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* Paths. (Executables in /usr are first tried with /usr stripped off.) */ -#define SHELL "/bin/sh" -#define PP "/usr/lib/ncpp" -#define IRREL "/usr/lib/irrel" -#define CEM "/usr/lib/ncem" -#define M2EM "/usr/lib/nm2em" -#define ENCODE "/usr/lib/em_encode" -#define OPT "/usr/lib/nopt" -#define CG "/usr/lib/ncg" -#define AS "/usr/lib/as" -#define LD "/usr/lib/ld" -#define CV "/usr/lib/cv" -#define LIBDIR "/usr/lib" -#define CRT "/usr/lib/ncrtso.o" -#define PEM "/usr/lib/npem" -#define PRT "/usr/lib/nprtso.o" -#define M2RT "/usr/lib/nm2rtso.o" -#define LIBC "/usr/lib/libd.a", "/usr/lib/libc.a" -#define LIBP "/usr/lib/libp.a", "/usr/lib/libc.a" -#define LIBM2 "/usr/lib/libm2.a", "/usr/lib/libc.a" -#define END "/usr/lib/libe.a", "/usr/lib/end.a" -#define M2DEF "-I/usr/lib/m2" - - -/* every pass that this program knows about has associated with it - a structure, containing such information as its name, where it - resides, the flags it accepts, and the like. -*/ -struct passinfo { - char *p_name; /* name of this pass */ - char *p_path; /* where is it */ - char *p_from; /* suffix of source (comma-separated list) */ - char *p_to; /* suffix of destination */ - char *p_acceptflags; /* comma separated list; format: - flag - flag* - flag=xxx - flag*=xxx[*] - where a star matches a, possibly empty, - string - */ - int p_flags; -#define INPUT 01 /* needs input file as argument */ -#define OUTPUT 02 /* needs output file as argument */ -#define LOADER 04 /* this pass is the loader */ -#define STDIN 010 /* reads from standard input */ -#define STDOUT 020 /* writes on standard output */ -#define NOCLEAN 040 /* do not remove target if this pass fails */ -#define O_OUTPUT 0100 /* -o outputfile, hack for as */ -#define PREPALWAYS 0200 /* always to be preprocessed */ -#define PREPCOND 0400 /* preprocessed when starting with '#' */ -#define PREPNOLN 01000 /* suppress line number info (cpp -P) */ -}; - -#define MAXHEAD 10 -#define MAXTAIL 5 -#define MAXPASS 7 - -/* Every language handled by this program has a "compile" structure - associated with it, describing the start-suffix, how the driver for - this language is called, which passes must be called, which flags - and arguments must be passed to these passes, etc. - The language is determined by the suffix of the argument program. - However, if this suffix does not determine a language (DEFLANG), - the callname is used. - Notice that the 's' suffix does not determine a language, because - the input file could have been derived from f.i. a C-program. - So, if you use "cc x.s", the C-runtime system will be used, but if - you use "as x.s", it will not. -*/ -struct compile { - char *c_suffix; /* starting suffix of this list of passes */ - char *c_callname; /* affects runtime system loaded with program */ - struct pass { - char *pp_name; /* name of the pass */ - char *pp_head[MAXHEAD]; /* args in front of filename */ - char *pp_tail[MAXTAIL]; /* args after filename */ - } c_passes[MAXPASS]; - int c_flags; -#define DEFLANG 010 /* this suffix determines a language */ -}; - -struct passinfo passinfo[] = { - { "cpp", PP, "CPP", "i", "wo=o,I*,D*,U*,P", INPUT|STDOUT }, - { "irrel", IRREL, "i", "i", "m", INPUT}, - { "cem", CEM, "i,c", "k", "m=o,p,wa=a,wo=o,ws=s,w,T*", INPUT|OUTPUT|PREPALWAYS }, - { "pc", PEM, "i,p", "k", "n=L,w,a,A,R", INPUT|OUTPUT|PREPCOND }, - { "m2", M2EM, "i,mod", "k", "n=L,w*,A,R,W*,3,I*", INPUT|OUTPUT|PREPCOND }, - { "encode", ENCODE, "i,e", "k", "", INPUT|STDOUT|PREPCOND|PREPNOLN }, - { "opt", OPT, "k", "m", "", STDIN|STDOUT }, - { "cg", CG, "m", "s", "O=p4", INPUT|OUTPUT }, - { "as", AS, "i,s", "o", "T*", INPUT|O_OUTPUT|PREPCOND }, - { "ld", LD, "o", "out", "i,s", INPUT|LOADER }, /* changed */ - { "cv", CV, "out", 0, "", INPUT|OUTPUT|NOCLEAN }, /* must come after loader */ - { 0} -}; - -#define PREP_FLAGS "-D_EM_WSIZE=2", "-D_EM_PSIZE=2", "-D_EM_SSIZE=2", \ - "-D_EM_LSIZE=4", "-D_EM_FSIZE=4", "-D_EM_DSIZE=8", \ - "-D__ACK__", "-D__minix", "-D__i86" - -struct pass preprocessor = { "cpp", - { PREP_FLAGS } - , {0} - }; - -struct pass prepnoln = { "cpp", - { PREP_FLAGS, "-P" } - , {0} - }; - -struct pass irrel = { "irrel", - {0} - }; - -/* The "*" in the arguments for the loader indicates the place where the - * fp-emulation library should come. - */ -struct compile passes[] = { -{ "c", "cc", - { { "cem", {"-L"}, {0} }, /* changed */ - { "opt", {0}, {0} }, - { "cg", {0}, {0} }, - { "as", {"-"}, {0} }, - { "ld", {CRT}, /* changed */ - {LIBC, "*", END}}, - { "cv", {0}, {0} } - }, - DEFLANG -}, -{ "p", "pc", - { { "pc", {0}, {0} }, - { "opt", {0}, {0} }, - { "cg", {0}, {0} }, - { "as", {"-"}, {0} }, - { "ld", {PRT}, - {LIBP, - "*", END}}, - { "cv", {0}, {0} } - }, - DEFLANG -}, -{ "mod", "m2", - { { "m2", {M2DEF}, {0} }, - { "opt", {0}, {0} }, - { "cg", {0}, {0} }, - { "as", {"-"}, {0} }, - { "ld", {M2RT}, - {LIBM2, - "*", END}}, - { "cv", {0}, {0} } - }, - DEFLANG -}, -{ "e", "encode", - { { "encode", {0}, {0}}, - { "opt", {0}, {0} }, - { "cg", {0}, {0} }, - { "as", {"-"}, {0} }, - { "ld", {0}, {"*", END}}, - { "cv", {0}, {0} } - }, - DEFLANG -}, -{ "s", "as", - { { "as", {0}, {0}} - }, - 0 -}, -{ "CPP", "cpp", - { { "cpp", {PREP_FLAGS}, {0}} - }, - DEFLANG -}, -{ 0}, -}; - -#define MAXARGC 150 /* maximum number of arguments allowed in a list */ -#define USTR_SIZE 64 /* maximum length of string variable */ - -typedef char USTRING[USTR_SIZE]; - -struct arglist { - int al_argc; - char *al_argv[MAXARGC]; -}; - -struct arglist CALLVEC; - -int kids = -1; - -char *o_FILE = "a.out"; /* default name for executable file */ - -#define init(a) ((a)->al_argc = 1) -#define cleanup(str) (str && remove(str)) - -char *ProgCall = 0; - -int RET_CODE = 0; - -char *stopsuffix; -int v_flag = 0; -int t_flag = 0; -int noexec = 0; -int fp_lib = 1; -int E_flag = 0; -int i_flag = 1; - - -USTRING curfil; -USTRING newfil; -struct arglist SRCFILES; -struct arglist LDIRS; -struct arglist LDFILES; -struct arglist GEN_LDFILES; -struct arglist FLAGS; - -char *tmpdir = "/tmp"; -char tmpname[64]; - -struct compile *compbase; -struct pass *loader; -struct passinfo *loaderinfo; -char *source; -int maxLlen; - -_PROTOTYPE(char *library, (char *nm )); -_PROTOTYPE(void trapcc, (int sig )); -_PROTOTYPE(int main, (int argc, char *argv [])); -_PROTOTYPE(int remove, (char *str )); -_PROTOTYPE(char *alloc, (unsigned u )); -_PROTOTYPE(int append, (struct arglist *al, char *arg )); -_PROTOTYPE(int concat, (struct arglist *al1, struct arglist *al2 )); -_PROTOTYPE(char *mkstr, (char *dst, char *arg1, char *arg2, char *arg3 )); -_PROTOTYPE(int basename, (char *str, char *dst )); -_PROTOTYPE(char *extension, (char *fln )); -_PROTOTYPE(int runvec, (struct arglist *vec, struct passinfo *pass, char *in, char *out )); -_PROTOTYPE(int prnum, (unsigned x )); -_PROTOTYPE(int prs, (char *str )); -_PROTOTYPE(int panic, (char *str )); -_PROTOTYPE(int pr_vec, (struct arglist *vec )); -_PROTOTYPE(int ex_vec, (struct arglist *vec )); -_PROTOTYPE(int mktempname, (char *nm )); -_PROTOTYPE(int mkbase, (void)); -_PROTOTYPE(int mkloader, (void)); -_PROTOTYPE(int needsprep, (char *name )); -_PROTOTYPE(int cfile, (char *name )); -_PROTOTYPE(char *apply, (struct passinfo *pinf, struct compile *cp, char *name, int passindex, int noremove, int first, char *resultname )); -_PROTOTYPE(int applicable, (struct passinfo *pinf, char *suffix )); -_PROTOTYPE(char *process, (char *name, int noremove )); -_PROTOTYPE(int mkvec, (struct arglist *call, char *in, char *out, struct pass *pass, struct passinfo *pinf )); -_PROTOTYPE(int callld, (struct arglist *in, char *out, struct pass *pass, struct passinfo *pinf )); -_PROTOTYPE(int clean, (struct arglist *c )); -_PROTOTYPE(int scanflags, (struct arglist *call, struct passinfo *pinf )); - - - -char * -library(nm) - char *nm; -{ - static char f[512]; - int Lcount; - - for (Lcount = 0; Lcount < LDIRS.al_argc; Lcount++) { - mkstr(f, LDIRS.al_argv[Lcount], "/lib", nm); - strcat(f, ".a"); - if (access(f, 0) != 0) { - f[strlen(f)-1] = 'a'; - if (access(f, 0) != 0) continue; - } - return f; - } - mkstr(f, LIBDIR, "/lib", nm); - strcat(f, ".a"); - if (access(f, 0) != 0) { - int i = strlen(f) - 1; - f[i] = 'a'; - if (access(f, 0) != 0) f[i] = 'A'; - } - return f; -} - -void trapcc(sig) - int sig; -{ - signal(sig, SIG_IGN); - if (kids != -1) kill(kids, sig); - cleanup(newfil); - cleanup(curfil); - exit(1); -} - -main(argc, argv) - char *argv[]; -{ - char *str; - char **argvec; - int count; - char *file; - - maxLlen = strlen(LIBDIR); - ProgCall = *argv++; - - mkbase(); - - if (signal(SIGHUP, SIG_IGN) != SIG_IGN) - signal(SIGHUP, trapcc); - if (signal(SIGINT, SIG_IGN) != SIG_IGN) - signal(SIGINT, trapcc); - if (signal(SIGQUIT, SIG_IGN) != SIG_IGN) - signal(SIGQUIT, trapcc); - while (--argc > 0) { - if (*(str = *argv++) != '-' || str[1] == 0) { - append(&SRCFILES, str); - continue; - } - - if (strcmp(str, "-com") == 0) { - i_flag = 0; - } else - if (strcmp(str, "-sep") == 0) { - i_flag = 1; - } else { - switch (str[1]) { - - case 'c': - stopsuffix = "o"; - if (str[2] == '.') stopsuffix = str + 3; - break; - case 'f': - fp_lib = (strcmp(str+2, "hard") != 0); - break; - case 'F': - case 'W': - /* Ignore. */ - break; - case 'L': - append(&LDIRS, &str[2]); - count = strlen(&str[2]); - if (count > maxLlen) maxLlen = count; - break; - case 'l': - append(&SRCFILES, library(&str[2])); - break; - case 'm': - /* Use -m, ignore -mxxx. */ - if (str[2] == 0) append(&FLAGS, str); - break; - case 'o': - if (argc-- >= 0) - o_FILE = *argv++; - break; - case 'S': - stopsuffix = "s"; - break; - case 'E': - E_flag = 1; - stopsuffix = "i"; - break; - case 'P': - stopsuffix = "i"; - append(&FLAGS, str); - break; - case 'v': - v_flag++; - if (str[2] == 'n') - noexec = 1; - break; - case 't': - /* save temporaries */ - t_flag++; - break; - case '.': - if (str[2] == 'o') { - /* no runtime start-off */ - loader->pp_head[0] = 0; - } - break; - case 'i': - i_flag++; - break; - case 'T': - tmpdir = &str[2]; - /*FALLTHROUGH*/ - default: - append(&FLAGS, str); - - } - } - } - - if (i_flag) append(&FLAGS, "-i"); - - mktempname(tmpname); - - count = SRCFILES.al_argc; - argvec = &(SRCFILES.al_argv[0]); - - while (count-- > 0) { - - file = *argvec++; - source = file; - - file = process(file, 1); - - if (file && ! stopsuffix) append(&LDFILES, file); - } - - clean(&SRCFILES); - - /* loader ... */ - if (RET_CODE == 0 && LDFILES.al_argc > 0) { - register struct passinfo *pp = passinfo; - - while (!(pp->p_flags & LOADER)) pp++; - mkstr(newfil, tmpname, pp->p_to, ""); - callld(&LDFILES, !((pp+1)->p_name) ? o_FILE : newfil, loader, pp); - if (RET_CODE == 0) { - register int i = GEN_LDFILES.al_argc; - - while (i-- > 0) { - remove(GEN_LDFILES.al_argv[i]); - free(GEN_LDFILES.al_argv[i]); - } - if ((++pp)->p_name) { - process(newfil, 0); - } - } - } - exit(RET_CODE); -} - -remove(str) - char *str; -{ - if (t_flag) - return; - if (v_flag) { - prs("rm "); - prs(str); - prs("\n"); - } - if (noexec) - return; - unlink(str); -} - -char * -alloc(u) - unsigned u; -{ - register char *p = malloc(u); - - if (p == 0) panic("no space\n"); - return p; -} - -append(al, arg) - struct arglist *al; - char *arg; -{ - char *a = alloc((unsigned) (strlen(arg) + 1)); - - strcpy(a, arg); - if (al->al_argc >= MAXARGC) - panic("argument list overflow\n"); - al->al_argv[(al->al_argc)++] = a; -} - -concat(al1, al2) - struct arglist *al1, *al2; -{ - register i = al2->al_argc; - register char **p = &(al1->al_argv[al1->al_argc]); - register char **q = &(al2->al_argv[0]); - - if ((al1->al_argc += i) >= MAXARGC) - panic("argument list overflow\n"); - while (i-- > 0) - *p++ = *q++; -} - -char * -mkstr(dst, arg1, arg2, arg3) - char *dst, *arg1, *arg2, *arg3; -{ - register char *p; - register char *q = dst; - - p = arg1; - while (*q++ = *p++); - q--; - p = arg2; - while (*q++ = *p++); - q--; - p = arg3; - while (*q++ = *p++); - q--; - return dst; -} - -basename(str, dst) - char *str; - register char *dst; -{ - register char *p1 = str; - register char *p2 = p1; - - while (*p1) - if (*p1++ == '/') - p2 = p1; - p1--; - while (*p1 != '.' && p1 > p2) p1--; - if (*p1 == '.') { - *p1 = '\0'; - while (*dst++ = *p2++); - *p1 = '.'; - } - else - while (*dst++ = *p2++); -} - -char * -extension(fln) - char *fln; -{ - register char *fn = fln; - - while (*fn) fn++; - while (fn > fln && *fn != '.') fn--; - if (fn != fln) return fn+1; - return (char *)0; -} - -runvec(vec, pass, in, out) - struct arglist *vec; - struct passinfo *pass; - char *in, *out; -{ - int pid, status; - int shifted = 0; - - if ( - strncmp(vec->al_argv[1], "/usr/", 5) == 0 - && - access(vec->al_argv[1] + 4, 1) == 0 - ) { - vec->al_argv[1] += 4; - shifted = 1; - } - - if (v_flag) { - pr_vec(vec); - if (pass->p_flags & STDIN) { - prs(" <"); - prs(in); - } - if (pass->p_flags & STDOUT && !E_flag) { - prs(" >"); - prs(out); - } - prs("\n"); - } - if (noexec) { - if (shifted) vec->al_argv[1] -= 4; - clean(vec); - return 1; - } - if ((pid = fork()) == 0) { /* start up the process */ - if (pass->p_flags & STDIN && strcmp(in, "-") != 0) { - /* redirect standard input */ - close(0); - if (open(in, 0) != 0) - panic("cannot open input file\n"); - } - if (pass->p_flags & STDOUT && !E_flag) { - /* redirect standard output */ - close(1); - if (creat(out, 0666) != 1) - panic("cannot create output file\n"); - } - ex_vec(vec); - } - if (pid == -1) - panic("no more processes\n"); - kids = pid; - wait(&status); - if (status) switch(status & 0177) { - case SIGHUP: - case SIGINT: - case SIGQUIT: - case SIGTERM: - case 0: - break; - default: - if (E_flag && (status & 0177) == SIGPIPE) break; - prs(vec->al_argv[1]); - prs(" died with signal "); - prnum(status & 0177); - prs("\n"); - } - if (shifted) vec->al_argv[1] -= 4; - clean(vec); - kids = -1; - return status ? ((RET_CODE = 1), 0) : 1; -} - -prnum(x) - register unsigned x; -{ - static char numbuf[8]; /* though it prints at most 3 characters */ - register char *cp = numbuf + sizeof(numbuf) - 1; - - *cp = '\0'; - while (x >= 10) { - *--cp = (x % 10) + '0'; - x /= 10; - } - *--cp = x + '0'; - prs(cp); - -} - -prs(str) - char *str; -{ - if (str && *str) - write(2, str, strlen(str)); -} - -panic(str) - char *str; -{ - prs(str); - trapcc(SIGINT); -} - -pr_vec(vec) - register struct arglist *vec; -{ - register char **ap = &vec->al_argv[1]; - - vec->al_argv[vec->al_argc] = 0; - prs(*ap); - while (*++ap) { - prs(" "); - if (strlen(*ap)) - prs(*ap); - else - prs("(empty)"); - } -} - -ex_vec(vec) - register struct arglist *vec; -{ - extern int errno; - - vec->al_argv[vec->al_argc] = 0; - execv(vec->al_argv[1], &(vec->al_argv[1])); - if (errno == ENOEXEC) { /* not an a.out, try it with the SHELL */ - vec->al_argv[0] = SHELL; - execv(SHELL, &(vec->al_argv[0])); - } - if (access(vec->al_argv[1], 1) == 0) { - /* File is executable. */ - prs("Cannot execute "); - prs(vec->al_argv[1]); - prs(". Not enough memory.\n"); - prs("Reduce the memory use of your system and try again\n"); - } else { - prs(vec->al_argv[1]); - prs(" is not executable\n"); - } - exit(1); -} - -mktempname(nm) - register char *nm; -{ - register int i; - register int pid = getpid(); - - mkstr(nm, tmpdir, "/", compbase->c_callname); - while (*nm) nm++; - - for (i = 9; i > 3; i--) { - *nm++ = (pid % 10) + '0'; - pid /= 10; - } - *nm++ = '.'; - *nm++ = '\0'; /* null termination */ -} - -mkbase() -{ - register struct compile *p = passes; - USTRING callname; - register int len; - - basename(ProgCall, callname); - len = strlen(callname); - while (p->c_suffix) { - if (strcmp(p->c_callname, callname+len-strlen(p->c_callname)) == 0) { - compbase = p; - mkloader(); - return; - } - p++; - } - /* we should not get here */ - panic("internal error\n"); -} - -mkloader() -{ - register struct passinfo *p = passinfo; - register struct pass *pass; - - while (!(p->p_flags & LOADER)) p++; - loaderinfo = p; - pass = &(compbase->c_passes[0]); - while (strcmp(pass->pp_name, p->p_name)) pass++; - loader = pass; -} - -needsprep(name) - char *name; -{ - int file; - char fc; - - file = open(name,0); - if (file <0) return 0; - if (read(file, &fc, 1) != 1) fc = 0; - close(file); - return fc == '#'; -} - -cfile(name) - char *name; -{ - while (*name != '\0' && *name != '.') - name++; - - if (*name == '\0') return 0; - return (*++name == 'c' && *++name == '\0'); -} - -char * -apply(pinf, cp, name, passindex, noremove, first, resultname) - register struct passinfo *pinf; - register struct compile *cp; - char *name, *resultname; -{ - /* Apply a pass, indicated by "pinf", with args in - cp->c_passes[passindex], to name "name", leaving the result - in a file with name "resultname", concatenated with result - suffix. - When neccessary, the preprocessor is run first. - If "noremove" is NOT set, the file "name" is removed. - */ - - struct arglist *call = &CALLVEC; - struct pass *pass = &(cp->c_passes[passindex]); - char *outname; - - if ( /* this pass is the first pass */ - first - && - ( /* preprocessor always needed */ - (pinf->p_flags & PREPALWAYS) - ||/* or only when "needsprep" says so */ - ( (pinf->p_flags & PREPCOND) && needsprep(name)) - ) - ) { - mkstr(newfil, tmpname, passinfo[0].p_to, ""); - mkvec(call, name, newfil, - (pinf->p_flags & PREPNOLN) ? &prepnoln : &preprocessor, - &passinfo[0]); - if (! runvec(call, &passinfo[0], name, newfil)) { - cleanup(newfil); - return 0; - } - - /* A .c file must always be mishandled by irrel. */ - if (cfile(name)) { - /* newfil is OK */ - mkvec(call, newfil, newfil, &irrel, &passinfo[1]); - if (! runvec(call, &passinfo[1], newfil, newfil)) { - cleanup(newfil); - return 0; - } - } - strcpy(curfil, newfil); - newfil[0] = '\0'; - name = curfil; - noremove = 0; - } - if (pinf->p_to) outname = mkstr(newfil, resultname, pinf->p_to, ""); - else outname = o_FILE; - mkvec(call, name, outname, pass, pinf); - if (! runvec(call, pinf, name, outname)) { - if (! (pinf->p_flags & NOCLEAN)) cleanup(outname); - if (! noremove) cleanup(name); - return 0; - } - if (! noremove) cleanup(name); - strcpy(curfil, newfil); - newfil[0] = '\0'; - return curfil; -} - -int -applicable(pinf, suffix) - struct passinfo *pinf; - char *suffix; -{ - /* Return one if the pass indicated by "pinfo" is applicable to - a file with suffix "suffix". - */ - register char *sfx = pinf->p_from; - int l; - - if (! suffix) return 0; - l = strlen(suffix); - while (*sfx) { - register char *p = sfx; - - while (*p && *p != ',') p++; - if (l == p - sfx && strncmp(sfx, suffix, l) == 0) { - return 1; - } - if (*p == ',') sfx = p+1; - else sfx = p; - } - return 0; -} - -char * -process(name, noremove) - char *name; -{ - register struct compile *cp = passes; - char *suffix = extension(name); - USTRING base; - register struct pass *pass; - register struct passinfo *pinf; - - if (E_flag) { - /* -E uses the cpp pass. */ - suffix = "CPP"; - } - - if (! suffix) return name; - - basename(name, base); - - while (cp->c_suffix) { - if ((cp->c_flags & DEFLANG) && - strcmp(cp->c_suffix, suffix) == 0) - break; - cp++; - } - if (! cp->c_suffix) cp = compbase; - pass = cp->c_passes; - while (pass->pp_name) { - int first = 1; - - for (pinf=passinfo; strcmp(pass->pp_name,pinf->p_name);pinf++) - ; - if (! (pinf->p_flags & LOADER) && applicable(pinf, suffix)) { - int cont = ! stopsuffix || ! pinf->p_to || - strcmp(stopsuffix, pinf->p_to) != 0; - name = apply(pinf, - cp, - name, - (int) (pass - cp->c_passes), - noremove, - first, - applicable(loaderinfo, pinf->p_to) || - !cont ? - strcat(base, ".") : - tmpname); - first = noremove = 0; - suffix = pinf->p_to; - if (!cont || !name) break; - } - pass++; - } - if (!noremove && name) - append(&GEN_LDFILES, name); - return name; -} - -mkvec(call, in, out, pass, pinf) - struct arglist *call; - char *in, *out; - struct pass *pass; - register struct passinfo *pinf; -{ - register int i; - - init(call); - append(call, pinf->p_path); - scanflags(call, pinf); - if (pass) for (i = 0; i < MAXHEAD; i++) - if (pass->pp_head[i]) - append(call, pass->pp_head[i]); - else break; - if (pinf->p_flags & INPUT && strcmp(in, "-") != 0) - append(call, in); - if (pinf->p_flags & OUTPUT) - append(call, out); - if (pinf->p_flags & O_OUTPUT) { - append(call, "-o"); - append(call, out); - } - if (pass) for (i = 0; i < MAXTAIL; i++) - if (pass->pp_tail[i]) - append(call, pass->pp_tail[i]); - else break; -} - -callld(in, out, pass, pinf) - struct arglist *in; - char *out; - struct pass *pass; - register struct passinfo *pinf; -{ - struct arglist *call = &CALLVEC; - register int i; - - init(call); - append(call, pinf->p_path); - scanflags(call, pinf); - append(call, "-o"); - append(call, out); - for (i = 0; i < MAXHEAD; i++) - if (pass->pp_head[i]) - append(call, pass->pp_head[i]); - else break; - if (pinf->p_flags & INPUT) - concat(call, in); - if (pinf->p_flags & OUTPUT) - append(call, out); - for (i = 0; i < MAXTAIL; i++) { - if (pass->pp_tail[i]) { - if (pass->pp_tail[i][0] == '-' && - pass->pp_tail[i][1] == 'l') { - append(call, library(&(pass->pp_tail[i][2]))); - } - else if (*(pass->pp_tail[i]) != '*') - append(call, pass->pp_tail[i]); - else if (fp_lib) - append(call, library("fp")); - } else break; - } - if (! runvec(call, pinf, (char *) 0, out)) { - cleanup(out); - RET_CODE = 1; - } -} - -clean(c) - register struct arglist *c; -{ - register int i; - - for (i = 1; i < c->al_argc; i++) { - free(c->al_argv[i]); - c->al_argv[i] = 0; - } - c->al_argc = 0; -} - -scanflags(call, pinf) - struct arglist *call; - struct passinfo *pinf; -{ - /* Find out which flags from FLAGS must be passed to pass "pinf", - and how. - Append them to "call" - */ - register int i; - USTRING flg; - - for (i = 0; i < FLAGS.al_argc; i++) { - register char *q = pinf->p_acceptflags; - - while (*q) { - register char *p = FLAGS.al_argv[i] + 1; - - while (*q && *q == *p) { - q++; p++; - } - if (*q == ',' || !*q) { - if (! *p) { - /* append literally */ - append(call, FLAGS.al_argv[i]); - } - break; - } - if (*q == '*') { - register char *s = flg; - - if (*++q != '=') { - /* append literally */ - append(call, FLAGS.al_argv[i]); - break; - } - *s++ = '-'; - if (*q) q++; /* skip ',' */ - while (*q && *q != ',' && *q != '*') { - /* copy replacement flag */ - *s++ = *q++; - } - if (*q == '*') { - /* copy rest */ - while (*p) *s++ = *p++; - } - *s = 0; - append(call, flg); - break; - } - if (*q == '=') { - /* copy replacement */ - register char *s = flg; - - *s++ = '-'; - q++; - while (*q && *q != ',') *s++ = *q++; - *s = 0; - append(call, flg); - break; - } - while (*q && *q++ != ',') - ; - } - } -} diff --git a/commands/sed/BUGS b/commands/sed/BUGS deleted file mode 100644 index b1e19bc1d..000000000 --- a/commands/sed/BUGS +++ /dev/null @@ -1,10 +0,0 @@ - -So far no regression over the historic sed are known. If you find a bug, -please provide a test-case (.sed, .in and .out, look into tests/) - if -possible try to debug the problem and propose a patch. - -We will focus on POSIX conformance and small size - GNU sed extensions are -most likely not accepted. - -Please report issues to: Rene Rebe - diff --git a/commands/sed/Makefile b/commands/sed/Makefile deleted file mode 100644 index 111c278ee..000000000 --- a/commands/sed/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# Makefile for minised - -# If your compiler does not support this flags, just remove them. -# They only ensure that no new warning regressions make it into the source. -CFLAGS = -Wall -Wwrite-strings - -minised: sedcomp.o sedexec.o - $(CC) $(LFLAGS) sedcomp.o sedexec.o -o minised - -sedcomp.o: sedcomp.c sed.h -sedexec.o: sedexec.c sed.h - -install: minised - install -o bin -m 755 minised /usr/bin/ - install -o bin -m 755 minised /bin/ - -clean: - rm -f minised sedcomp.o sedexec.o - -check: minised - cd tests; ./run ../minised - diff --git a/commands/sed/README b/commands/sed/README deleted file mode 100644 index b832d5330..000000000 --- a/commands/sed/README +++ /dev/null @@ -1,81 +0,0 @@ - small-sed - by Eric S. Raymond, - and Rene Rebe - -This is a smaller, cheaper, and faster SED utility. Minix uses it. GNU used -to use it, until they built their own sed around an extended (some would -say over-extended) regexp package and it is used for embedded tasks (for -example by the T2 SDE - http://www.t2-project.org). - -The original sed 1.0 was written in three pieces; sed.h, sedcomp.c, sedexec.c. -Some Minix hacker ran them together into a single-file version, mnsed.c which -is not supported and shipped these days; if changes are needed for Minix please -send a patch to the normal source. - -The 1.2 version (9 Oct 1996) add mnsed's support for detecting -truncated hold spaces. The mnsed version is missing one feature in -of the 1.2 version; support of +. Also, the multiple-file I/O is -organized slightly differently. - -The 1.3 version added a bug fix by Tom Oehser, and the `L' command. Also -this program is now distributed under GPL. - -The 1.5 version incooperated a lot of bug fixes by Rene Rebe as well as -a real test suite. Also the function declaration and definition have been -converted from the K&R C to ANSI C. - -The 1.6 version includes support for the n'th match for the substitude command -as well as support for predefined character classes and only writes lines -with newline if one was present in the input line (compatible with GNU sed). - -The 1.7 version fixed a segmentation fault with empty regular expressions, -not to leak other buffer content for groups of commands and escaping -numerical seperators in regular expressions by disabling obscure code. -Additionally compilation with older compilers as well as warnings with the -latest gcc versions have been corrected. - -The 1.8 version fixes matching of some escaped characters (a regression -introduced with \+ star matching), \+ star matching to corretly copy -and mark the internal bytecode representation, back references inside lhs -regular expressions matching (to work at all) and marking the correct -regular expression for star matches. - -The 1.9 version included a microoptimization shaving some bytes off the -binary and some cpu cycles at run time, reusing the previous regular -expressions for empty ones, predefined character classes with control -characters, handling of escaped ampesands and support for backreference -\0 and Kleene star operator on groups. - -The 1.10 version fixed a special case of grouped star matching where -\+1..n overwrote the last match, not to infinite loop on certain zero match -grouped star cases and not to crash on w(rite to file). The version also -no longer falls into the conservative end-of-file matching mode when just -end-of-line matching was used. - -The 1.11 version again fixed w(rite to file) handling to correctly honor -/dev/stdout and /dev/stderr as GNU sed does and thus keep the streams in -sync. Some unused variables have been removed and a two diagnostics -fixed to be printed correctly. - -The 1.12 version fixed the l(ist) command to actually work, some tiny -optimizations have been performed as well as some more compiler warnings -fixed. - -Makefile -- how to build sed -sed.h -- declarations and structures -sedcomp.c -- sed pattern compilation -sedexec.c -- sed program execution -sed.1 -- source for the man page -tests/ -- a small set of sed tests - -For some releases the man page in the man format. - -Surf to - - http://www.exactcode.de/oss/minised/ - http://www.catb.org/~esr/ - -for updates of this software. There is a sed FAQ kept at these -locations: - - http://www.dreamwvr.com/sed-info/sed-faq.html diff --git a/commands/sed/sed.h b/commands/sed/sed.h deleted file mode 100644 index 13db9207d..000000000 --- a/commands/sed/sed.h +++ /dev/null @@ -1,85 +0,0 @@ -/* sed.h -- types and constants for the stream editor - Copyright (C) 1995-2003 Eric S. Raymond - Copyright (C) 2004-2005 Rene Rebe -*/ - -#define TRUE 1 -#define FALSE 0 - -/* data area sizes used by both modules */ -#define MAXBUF 4000 /* current line buffer size */ -#define MAXAPPENDS 20 /* maximum number of appends */ -#define MAXTAGS 9 /* tagged patterns are \1 to \9 */ -#define MAXCMDS 200 /* maximum number of compiled commands */ -#define MAXLINES 256 /* max # numeric addresses to compile */ - -/* constants for compiled-command representation */ -#define EQCMD 0x01 /* = -- print current line number */ -#define ACMD 0x02 /* a -- append text after current line */ -#define BCMD 0x03 /* b -- branch to label */ -#define CCMD 0x04 /* c -- change current line */ -#define DCMD 0x05 /* d -- delete all of pattern space */ -#define CDCMD 0x06 /* D -- delete first line of pattern space */ -#define GCMD 0x07 /* g -- copy hold space to pattern space */ -#define CGCMD 0x08 /* G -- append hold space to pattern space */ -#define HCMD 0x09 /* h -- copy pattern space to hold space */ -#define CHCMD 0x0A /* H -- append hold space to pattern space */ -#define ICMD 0x0B /* i -- insert text before current line */ -#define LCMD 0x0C /* l -- print pattern space in escaped form */ -#define CLCMD 0x20 /* L -- hexdump */ -#define NCMD 0x0D /* n -- get next line into pattern space */ -#define CNCMD 0x0E /* N -- append next line to pattern space */ -#define PCMD 0x0F /* p -- print pattern space to output */ -#define CPCMD 0x10 /* P -- print first line of pattern space */ -#define QCMD 0x11 /* q -- exit the stream editor */ -#define RCMD 0x12 /* r -- read in a file after current line */ -#define SCMD 0x13 /* s -- regular-expression substitute */ -#define TCMD 0x14 /* t -- branch on last substitute successful */ -#define CTCMD 0x15 /* T -- branch on last substitute failed */ -#define WCMD 0x16 /* w -- write pattern space to file */ -#define CWCMD 0x17 /* W -- write first line of pattern space */ -#define XCMD 0x18 /* x -- exhange pattern and hold spaces */ -#define YCMD 0x19 /* y -- transliterate text */ - -typedef struct cmd_t /* compiled-command representation */ -{ - char *addr1; /* first address for command */ - char *addr2; /* second address for command */ - union - { - char *lhs; /* s command lhs */ - struct cmd_t *link; /* label link */ - } u; - char command; /* command code */ - char *rhs; /* s command replacement string */ - FILE *fout; /* associated output file descriptor */ - struct - { - unsigned allbut : 1; /* was negation specified? */ - unsigned global : 1; /* was p postfix specified? */ - unsigned print : 2; /* was g postfix specified? */ - unsigned inrange : 1; /* in an address range? */ - } flags; - unsigned nth; /* sed nth occurance */ -} -sedcmd; /* use this name for declarations */ - -#define BAD ((char *) -1) /* guaranteed not a string ptr */ - -/* address and regular expression compiled-form markers */ -#define STAR 1 /* marker for Kleene star */ -#define CCHR 2 /* non-newline character to be matched follows */ -#define CDOT 4 /* dot wild-card marker */ -#define CCL 6 /* character class follows */ -#define CNL 8 /* match line start */ -#define CDOL 10 /* match line end */ -#define CBRA 12 /* tagged pattern start marker */ -#define CKET 14 /* tagged pattern end marker */ -#define CBACK 16 /* backslash-digit pair marker */ -#define CLNUM 18 /* numeric-address index follows */ -#define CEND 20 /* symbol for end-of-source */ -#define CEOF 22 /* end-of-field mark */ - -#define bits(b) (1 << (b)) - -/* sed.h ends here */ diff --git a/commands/sed/sedcomp.c b/commands/sed/sedcomp.c deleted file mode 100644 index 95eb8c549..000000000 --- a/commands/sed/sedcomp.c +++ /dev/null @@ -1,956 +0,0 @@ -/* sedcomp.c -- stream editor main and compilation phase - Copyright (C) 1995-2003 Eric S. Raymond - Copyright (C) 2004-2006 Rene Rebe - - The stream editor compiles its command input (from files or -e options) -into an internal form using compile() then executes the compiled form using -execute(). Main() just initializes data structures, interprets command line -options, and calls compile() and execute() in appropriate sequence. - The data structure produced by compile() is an array of compiled-command -structures (type sedcmd). These contain several pointers into pool[], the -regular-expression and text-data pool, plus a command code and g & p flags. -In the special case that the command is a label the struct will hold a ptr -into the labels array labels[] during most of the compile, until resolve() -resolves references at the end. - The operation of execute() is described in its source module. -*/ - -#include /* exit */ -#include /* uses getc, fprintf, fopen, fclose */ -#include /* isdigit */ -#include /* strcmp */ -#include "sed.h" /* command type struct and name defines */ - -/***** public stuff ******/ - -#define MAXCMDS 200 /* maximum number of compiled commands */ -#define MAXLINES 256 /* max # numeric addresses to compile */ - -/* main data areas */ -char linebuf[MAXBUF+1]; /* current-line buffer */ -sedcmd cmds[MAXCMDS+1]; /* hold compiled commands */ -long linenum[MAXLINES]; /* numeric-addresses table */ - -/* miscellaneous shared variables */ -int nflag; /* -n option flag */ -int eargc; /* scratch copy of argument count */ -sedcmd *pending = NULL; /* next command to be executed */ - -int last_line_used = 0; /* last line address ($) was used */ - -void die (const char* msg) { - fprintf(stderr, "sed: "); - fprintf(stderr, msg, linebuf); - fprintf(stderr, "\n"); - exit(2); -} - -/***** module common stuff *****/ - -#define POOLSIZE 10000 /* size of string-pool space */ -#define WFILES 10 /* max # w output files that can be compiled */ -#define RELIMIT 256 /* max chars in compiled RE */ -#define MAXDEPTH 20 /* maximum {}-nesting level */ -#define MAXLABS 50 /* max # of labels that can be handled */ - -#define SKIPWS(pc) while ((*pc==' ') || (*pc=='\t')) pc++ -#define IFEQ(x, v) if (*x == v) x++ , /* do expression */ - -/* error messages */ -static char AGMSG[] = "garbled address %s"; -static char CGMSG[] = "garbled command %s"; -static char TMTXT[] = "too much text: %s"; -static char AD1NG[] = "no addresses allowed for %s"; -static char AD2NG[] = "only one address allowed for %s"; -static char TMCDS[] = "too many commands, last was %s"; -static char COCFI[] = "cannot open command-file %s"; -static char UFLAG[] = "unknown flag %c"; -/*static char COOFI[] = "cannot open %s";*/ -static char CCOFI[] = "cannot create %s"; -static char ULABL[] = "undefined label %s"; -static char TMLBR[] = "too many {'s"; -static char FRENL[] = "first RE must be non-null"; -static char NSCAX[] = "no such command as %s"; -static char TMRBR[] = "too many }'s"; -static char DLABL[] = "duplicate label %s"; -static char TMLAB[] = "too many labels: %s"; -static char TMWFI[] = "too many w files"; -static char REITL[] = "RE too long: %s"; -static char TMLNR[] = "too many line numbers"; -static char TRAIL[] = "command \"%s\" has trailing garbage"; -static char RETER[] = "RE not terminated: %s"; -static char CCERR[] = "unknown character class: %s"; - -/* cclass to c function mapping ,-) */ -const char* cclasses[] = { - "alnum", "a-zA-Z0-9", - "lower", "a-z", - "space", " \f\n\r\t\v", - "alpha", "a-zA-Z", - "digit", "0-9", - "upper", "A-Z", - "blank", " \t", - "xdigit", "0-9A-Fa-f", - "cntrl", "\x01-\x1f\x7e", - "print", " -\x7e", - "graph", "!-\x7e", - "punct", "!-/:-@[-`{-\x7e", - NULL, NULL}; - -typedef struct /* represent a command label */ -{ - char *name; /* the label name */ - sedcmd *last; /* it's on the label search list */ - sedcmd *address; /* pointer to the cmd it labels */ -} label; - -/* label handling */ -static label labels[MAXLABS]; /* here's the label table */ -static label *lab = labels + 1; /* pointer to current label */ -static label *lablst = labels; /* header for search list */ - -/* string pool for regular expressions, append text, etc. etc. */ -static char pool[POOLSIZE]; /* the pool */ -static char *fp = pool; /* current pool pointer */ -static char *poolend = pool + POOLSIZE; /* pointer past pool end */ - -/* compilation state */ -static FILE *cmdf = NULL; /* current command source */ -static char *cp = linebuf; /* compile pointer */ -static sedcmd *cmdp = cmds; /* current compiled-cmd ptr */ -static char *lastre = NULL; /* old RE pointer */ -static int bdepth = 0; /* current {}-nesting level */ -static int bcount = 0; /* # tagged patterns in current RE */ -static char **eargv; /* scratch copy of argument list */ - -/* compilation flags */ -static int eflag; /* -e option flag */ -static int gflag; /* -g option flag */ - -/* prototypes */ -static char *address(char *expbuf); -static char *gettext(char* txp); -static char *recomp(char *expbuf, char redelim); -static char *rhscomp(char* rhsp, char delim); -static char *ycomp(char *ep, char delim); -static int cmdcomp(char cchar); -static int cmdline(char *cbuf); -static label *search(label *ptr); -static void compile(void); -static void resolve(void); - -/* sedexec.c protypes */ -void execute(char* file); - -/* main sequence of the stream editor */ -int main(int argc, char *argv[]) -{ - eargc = argc; /* set local copy of argument count */ - eargv = argv; /* set local copy of argument list */ - cmdp->addr1 = pool; /* 1st addr expand will be at pool start */ - if (eargc == 1) - exit(0); /* exit immediately if no arguments */ - - /* scan through the arguments, interpreting each one */ - while ((--eargc > 0) && (**++eargv == '-')) - switch (eargv[0][1]) - { - case 'e': - eflag++; compile(); /* compile with e flag on */ - eflag = 0; - continue; /* get another argument */ - case 'f': - if (eargc-- <= 0) /* barf if no -f file */ - exit(2); - if ((cmdf = fopen(*++eargv, "r")) == NULL) - { - fprintf(stderr, COCFI, *eargv); - exit(2); - } - compile(); /* file is O.K., compile it */ - fclose(cmdf); - continue; /* go back for another argument */ - case 'g': - gflag++; /* set global flag on all s cmds */ - continue; - case 'n': - nflag++; /* no print except on p flag or w */ - continue; - default: - fprintf(stdout, UFLAG, eargv[0][1]); - continue; - } - - if (cmdp == cmds) /* no commands have been compiled */ - { - eargv--; eargc++; - eflag++; compile(); eflag = 0; - eargv++; eargc--; - } - - if (bdepth) /* we have unbalanced squigglies */ - die(TMLBR); - - lablst->address = cmdp; /* set up header of label linked list */ - resolve(); /* resolve label table indirections */ - if (eargc <= 0) /* if there were no -e commands */ - execute(NULL); /* execute commands from stdin only */ - else while(--eargc>=0) /* else execute only -e commands */ - execute(*eargv++); - exit(0); /* everything was O.K. if we got here */ -} - -#define H 0x80 /* 128 bit, on if there's really code for command */ -#define LOWCMD 56 /* = '8', lowest char indexed in cmdmask */ - -/* indirect through this to get command internal code, if it exists */ -static char cmdmask[] = -{ - 0, 0, H, 0, 0, H+EQCMD,0, 0, - 0, 0, 0, 0, H+CDCMD,0, 0, CGCMD, - CHCMD, 0, 0, 0, H+CLCMD,0, CNCMD, 0, - CPCMD, 0, 0, 0, H+CTCMD,0, 0, H+CWCMD, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, H+ACMD, H+BCMD, H+CCMD, DCMD, 0, 0, GCMD, - HCMD, H+ICMD, 0, 0, H+LCMD, 0, NCMD, 0, - PCMD, H+QCMD, H+RCMD, H+SCMD, H+TCMD, 0, 0, H+WCMD, - XCMD, H+YCMD, 0, H+BCMD, 0, H, 0, 0, -}; - -/* precompile sed commands out of a file */ -static void compile(void) -{ - char ccode; - - for(;;) /* main compilation loop */ - { - SKIPWS(cp); - if (*cp == ';') { - cp++; - SKIPWS(cp); - } - - if (*cp == '\0' || *cp == '#') /* get a new command line */ - if (cmdline(cp = linebuf) < 0) - break; - SKIPWS(cp); - - if (*cp == '\0' || *cp == '#') /* a comment */ - continue; - - /* compile first address */ - if (fp > poolend) - die(TMTXT); - else if ((fp = address(cmdp->addr1 = fp)) == BAD) - die(AGMSG); - - if (fp == cmdp->addr1) /* if empty RE was found */ - { - if (lastre) /* if there was previous RE */ - cmdp->addr1 = lastre; /* use it */ - else - die(FRENL); - } - else if (fp == NULL) /* if fp was NULL */ - { - fp = cmdp->addr1; /* use current pool location */ - cmdp->addr1 = NULL; - } - else - { - lastre = cmdp->addr1; - if (*cp == ',' || *cp == ';') /* there's 2nd addr */ - { - cp++; - if (fp > poolend) die(TMTXT); - fp = address(cmdp->addr2 = fp); - if (fp == BAD || fp == NULL) die(AGMSG); - if (fp == cmdp->addr2) - cmdp->addr2 = lastre; - else - lastre = cmdp->addr2; - } - else - cmdp->addr2 = NULL; /* no 2nd address */ - } - if (fp > poolend) die(TMTXT); - - SKIPWS(cp); /* discard whitespace after address */ - - if (*cp == '!') { - cmdp->flags.allbut = 1; - cp++; SKIPWS(cp); - } - - /* get cmd char, range-check it */ - if ((*cp < LOWCMD) || (*cp > '~') - || ((ccode = cmdmask[*cp - LOWCMD]) == 0)) - die(NSCAX); - - cmdp->command = ccode & ~H; /* fill in command value */ - if ((ccode & H) == 0) /* if no compile-time code */ - cp++; /* discard command char */ - else if (cmdcomp(*cp++)) /* execute it; if ret = 1 */ - continue; /* skip next line read */ - - if (++cmdp >= cmds + MAXCMDS) die(TMCDS); - - SKIPWS(cp); /* look for trailing stuff */ - if (*cp != '\0') - { - if (*cp == ';') - { - continue; - } - else if (*cp != '#' && *cp != '}') - die(TRAIL); - } - } -} - -/* compile a single command */ -static int cmdcomp(char cchar) -{ - static sedcmd **cmpstk[MAXDEPTH]; /* current cmd stack for {} */ - static const char *fname[WFILES]; /* w file name pointers */ - static FILE *fout[WFILES]; /* w file file ptrs */ - static int nwfiles = 2; /* count of open w files */ - int i; /* indexing dummy used in w */ - sedcmd *sp1, *sp2; /* temps for label searches */ - label *lpt; /* ditto, and the searcher */ - char redelim; /* current RE delimiter */ - - fout[0] = stdout; - fout[1] = stderr; - - fname[0] = "/dev/stdout"; - fname[1] = "/dev/stderr"; - - switch(cchar) - { - case '{': /* start command group */ - cmdp->flags.allbut = !cmdp->flags.allbut; - cmpstk[bdepth++] = &(cmdp->u.link); - if (++cmdp >= cmds + MAXCMDS) die(TMCDS); - if (*cp == '\0') *cp++ = ';', *cp = '\0'; /* get next cmd w/o lineread */ - return(1); - - case '}': /* end command group */ - if (cmdp->addr1) die(AD1NG); /* no addresses allowed */ - if (--bdepth < 0) die(TMRBR); /* too many right braces */ - *cmpstk[bdepth] = cmdp; /* set the jump address */ - return(1); - - case '=': /* print current source line number */ - case 'q': /* exit the stream editor */ - if (cmdp->addr2) die(AD2NG); - break; - - case ':': /* label declaration */ - if (cmdp->addr1) die(AD1NG); /* no addresses allowed */ - fp = gettext(lab->name = fp); /* get the label name */ - if ((lpt = search(lab))) /* does it have a double? */ - { - if (lpt->address) die(DLABL); /* yes, abort */ - } - else /* check that it doesn't overflow label table */ - { - lab->last = NULL; - lpt = lab; - if (++lab >= labels + MAXLABS) die(TMLAB); - } - lpt->address = cmdp; - return(1); - - case 'b': /* branch command */ - case 't': /* branch-on-succeed command */ - case 'T': /* branch-on-fail command */ - SKIPWS(cp); - if (*cp == '\0') /* if branch is to start of cmds... */ - { - /* add current command to end of label last */ - if ((sp1 = lablst->last)) - { - while((sp2 = sp1->u.link)) - sp1 = sp2; - sp1->u.link = cmdp; - } - else /* lablst->last == NULL */ - lablst->last = cmdp; - break; - } - fp = gettext(lab->name = fp); /* else get label into pool */ - if ((lpt = search(lab))) /* enter branch to it */ - { - if (lpt->address) - cmdp->u.link = lpt->address; - else - { - sp1 = lpt->last; - while((sp2 = sp1->u.link)) - sp1 = sp2; - sp1->u.link = cmdp; - } - } - else /* matching named label not found */ - { - lab->last = cmdp; /* add the new label */ - lab->address = NULL; /* it's forward of here */ - if (++lab >= labels + MAXLABS) /* overflow if last */ - die(TMLAB); - } - break; - - case 'a': /* append text */ - case 'i': /* insert text */ - case 'r': /* read file into stream */ - if (cmdp->addr2) die(AD2NG); - case 'c': /* change text */ - if ((*cp == '\\') && (*++cp == '\n')) cp++; - fp = gettext(cmdp->u.lhs = fp); - break; - - case 'D': /* delete current line in hold space */ - cmdp->u.link = cmds; - break; - - case 's': /* substitute regular expression */ - if (*cp == 0) /* get delimiter from 1st ch */ - die(RETER); - else - redelim = *cp++; - - if ((fp = recomp(cmdp->u.lhs = fp, redelim)) == BAD) - die(CGMSG); - if (fp == cmdp->u.lhs) { /* if compiled RE zero len */ - if (lastre) { - cmdp->u.lhs = lastre; /* use the previous one */ - cp++; /* skip delim */ - } - else - die(FRENL); - } - else /* otherwise */ - lastre = cmdp->u.lhs; /* save the one just found */ - - if ((cmdp->rhs = fp) > poolend) die(TMTXT); - if ((fp = rhscomp(cmdp->rhs, redelim)) == BAD) die(CGMSG); - if (gflag) cmdp->flags.global++; - while (*cp == 'g' || *cp == 'p' || *cp == 'P' || isdigit(*cp)) - { - IFEQ(cp, 'g') cmdp->flags.global++; - IFEQ(cp, 'p') cmdp->flags.print = 1; - IFEQ(cp, 'P') cmdp->flags.print = 2; - if(isdigit(*cp)) - { - if (cmdp->nth) - break; /* no multiple n args */ - - cmdp->nth = atoi(cp); /* check 0? */ - while (isdigit(*cp)) cp++; - } - } - - case 'l': /* list pattern space */ - case 'L': /* dump pattern space */ - if (*cp == 'w') - cp++; /* and execute a w command! */ - else - break; /* s or L or l is done */ - - case 'w': /* write-pattern-space command */ - case 'W': /* write-first-line command */ - if (nwfiles >= WFILES) die(TMWFI); - fname[nwfiles] = fp; - fp = gettext((fname[nwfiles] = fp, fp)); /* filename will be in pool */ - for(i = nwfiles-1; i >= 0; i--) /* match it in table */ - if (strcmp(fname[nwfiles], fname[i]) == 0) - { - cmdp->fout = fout[i]; - return(0); - } - /* if didn't find one, open new out file */ - if ((cmdp->fout = fopen(fname[nwfiles], "w")) == NULL) - { - fprintf(stderr, CCOFI, fname[nwfiles]); - exit(2); - } - fout[nwfiles++] = cmdp->fout; - break; - - case 'y': /* transliterate text */ - fp = ycomp(cmdp->u.lhs = fp, *cp++); /* compile translit */ - if (fp == BAD) die(CGMSG); /* fail on bad form */ - if (fp > poolend) die(TMTXT); /* fail on overflow */ - break; - } - return(0); /* succeeded in interpreting one command */ -} - -/* generate replacement string for substitute command right hand side - rhsp: place to compile expression to - delim: regular-expression end-mark to look for */ -static char *rhscomp(char* rhsp, char delim) /* uses bcount */ -{ - register char *p = cp; - - for(;;) - /* copy for the likely case it is not s.th. special */ - if ((*rhsp = *p++) == '\\') /* back reference or escape */ - { - if (*p >= '0' && *p <= '9') /* back reference */ - { - dobackref: - *rhsp = *p++; - /* check validity of pattern tag */ - if (*rhsp > bcount + '0') - return(BAD); - *rhsp++ |= 0x80; /* mark the good ones */ - } - else /* escape */ - { - switch (*p) { - case 'n': *rhsp = '\n'; break; - case 'r': *rhsp = '\r'; break; - case 't': *rhsp = '\t'; break; - default: *rhsp = *p; - } - rhsp++; p++; - } - } - else if (*rhsp == delim) /* found RE end, hooray... */ - { - *rhsp++ = '\0'; /* cap the expression string */ - cp = p; - return(rhsp); /* pt at 1 past the RE */ - } - else if (*rhsp == '&') /* special case, convert to backref \0 */ - { - *--p = '0'; - goto dobackref; - } - else if (*rhsp++ == '\0') /* last ch not RE end, help! */ - return(BAD); -} - -/* compile a regular expression to internal form - expbuf: place to compile it to - redelim: RE end-marker to look for */ -static char *recomp(char *expbuf, char redelim) /* uses cp, bcount */ -{ - register char *ep = expbuf; /* current-compiled-char pointer */ - register char *sp = cp; /* source-character ptr */ - register int c; /* current-character pointer */ - char negclass; /* all-but flag */ - char *lastep; /* ptr to last expr compiled */ - char *lastep2; /* dito, but from the last loop */ - char *svclass; /* start of current char class */ - char brnest[MAXTAGS]; /* bracket-nesting array */ - char *brnestp; /* ptr to current bracket-nest */ - char *pp; /* scratch pointer */ - int classct; /* class element count */ - int tags; /* # of closed tags */ - - if (*cp == redelim) { /* if first char is RE endmarker */ - return(ep); - } - - lastep = lastep2 = NULL; /* there's no previous RE */ - brnestp = brnest; /* initialize ptr to brnest array */ - tags = bcount = 0; /* initialize counters */ - - if ((*ep++ = (*sp == '^'))) /* check for start-of-line syntax */ - sp++; - - for (;;) - { - if (*sp == 0) /* no termination */ - die (RETER); - if (ep >= expbuf + RELIMIT) /* match is too large */ - return(cp = sp, BAD); - if ((c = *sp++) == redelim) /* found the end of the RE */ - { - cp = sp; - if (brnestp != brnest) /* \(, \) unbalanced */ - return(BAD); - *ep++ = CEOF; /* write end-of-pattern mark */ - return(ep); /* return ptr to compiled RE */ - } - - lastep = lastep2; - lastep2 = ep; - - switch (c) - { - case '\\': - if ((c = *sp++) == '(') /* start tagged section */ - { - if (bcount >= MAXTAGS) - return(cp = sp, BAD); - *brnestp++ = bcount; /* update tag stack */ - *ep++ = CBRA; /* enter tag-start */ - *ep++ = bcount++; /* bump tag count */ - lastep2 = NULL; - continue; - } - else if (c == ')') /* end tagged section */ - { - if (brnestp <= brnest) /* extra \) */ - return(cp = sp, BAD); - *ep++ = CKET; /* enter end-of-tag */ - *ep++ = *--brnestp; /* pop tag stack */ - tags++; /* count closed tags */ - for (lastep2 = ep-1; *lastep2 != CBRA; ) - --lastep2; /* FIXME: lastep becomes start */ - continue; - } - else if (c >= '1' && c <= '9' && c != redelim) /* tag use, if !delim */ - { - if ((c -= '1') >= tags) /* too few */ - return(BAD); - *ep++ = CBACK; /* enter tag mark */ - *ep++ = c; /* and the number */ - continue; - } - else if (c == '\n') /* escaped newline no good */ - return(cp = sp, BAD); - else if (c == 'n') /* match a newline */ - c = '\n'; - else if (c == 't') /* match a tab */ - c = '\t'; - else if (c == 'r') /* match a return */ - c = '\r'; - else if (c == '+') /* 1..n repeat of previous pattern */ - { - if (lastep == NULL) /* if + not first on line */ - goto defchar; /* match a literal + */ - pp = ep; /* else save old ep */ - *ep++ = *lastep++ | STAR; /* flag the copy */ - while (lastep < pp) /* so we can blt the pattern */ - *ep++ = *lastep++; - lastep2 = lastep; /* no new expression */ - continue; - } - goto defchar; /* else match \c */ - - case '\0': /* ignore nuls */ - continue; - - case '\n': /* trailing pattern delimiter is missing */ - return(cp = sp, BAD); - - case '.': /* match any char except newline */ - *ep++ = CDOT; - continue; - - case '*': /* 0..n repeat of previous pattern */ - if (lastep == NULL) /* if * isn't first on line */ - goto defchar; /* match a literal * */ - *lastep |= STAR; /* flag previous pattern */ - lastep2 = lastep; /* no new expression */ - continue; - - case '$': /* match only end-of-line */ - if (*sp != redelim) /* if we're not at end of RE */ - goto defchar; /* match a literal $ */ - *ep++ = CDOL; /* insert end-symbol mark */ - continue; - - case '[': /* begin character set pattern */ - if (ep + 17 >= expbuf + RELIMIT) - die(REITL); - *ep++ = CCL; /* insert class mark */ - if ((negclass = ((c = *sp++) == '^'))) - c = *sp++; - svclass = sp; /* save ptr to class start */ - do { - if (c == '\0') die(CGMSG); - /* handle predefined character classes */ - if (c == '[' && *sp == ':') - { - /* look for the matching ":]]" */ - char *p; - const char *p2; - for (p = sp+3; *p; p++) - if (*p == ']' && - *(p-1) == ']' && - *(p-2) == ':') - { - char cc[8]; - const char **it; - p2 = sp+1; - for (p2 = sp+1; - p2 < p-2 && p2-sp-1 < sizeof(cc); - p2++) - cc[p2-sp-1] = *p2; - cc[p2-sp-1] = 0; /* termination */ - - it = cclasses; - while (*it && strcmp(*it, cc)) - it +=2; - if (!*it++) - die(CCERR); - - /* generate mask */ - p2 = *it; - while (*p2) { - if (p2[1] == '-' && p2[2]) { - for (c = *p2; c <= p2[2]; c++) - ep[c >> 3] |= bits(c & 7); - p2 += 3; - } - else { - c = *p2++; - ep[c >> 3] |= bits(c & 7); - } - } - sp = p; c = 0; break; - } - } - - /* handle character ranges */ - if (c == '-' && sp > svclass && *sp != ']') - for (c = sp[-2]; c < *sp; c++) - ep[c >> 3] |= bits(c & 7); - - /* handle escape sequences in sets */ - if (c == '\\') - { - if ((c = *sp++) == 'n') - c = '\n'; - else if (c == 't') - c = '\t'; - else if (c == 'r') - c = '\r'; - } - - /* enter (possibly translated) char in set */ - if (c) - ep[c >> 3] |= bits(c & 7); - } while - ((c = *sp++) != ']'); - - /* invert the bitmask if all-but was specified */ - if (negclass) - for(classct = 0; classct < 16; classct++) - ep[classct] ^= 0xFF; - ep[0] &= 0xFE; /* never match ASCII 0 */ - ep += 16; /* advance ep past set mask */ - continue; - - defchar: /* match literal character */ - default: /* which is what we'd do by default */ - *ep++ = CCHR; /* insert character mark */ - *ep++ = c; - } - } -} - -/* read next command from -e argument or command file */ -static int cmdline(char *cbuf) /* uses eflag, eargc, cmdf */ -{ - register int inc; /* not char because must hold EOF */ - - cbuf--; /* so pre-increment points us at cbuf */ - - /* e command flag is on */ - if (eflag) - { - register char *p; /* ptr to current -e argument */ - static char *savep; /* saves previous value of p */ - - if (eflag > 0) /* there are pending -e arguments */ - { - eflag = -1; - if (eargc-- <= 0) - exit(2); /* if no arguments, barf */ - - /* else transcribe next e argument into cbuf */ - p = *++eargv; - while((*++cbuf = *p++)) - if (*cbuf == '\\') - { - if ((*++cbuf = *p++) == '\0') - return(savep = NULL, -1); - else - continue; - } - else if (*cbuf == '\n') /* end of 1 cmd line */ - { - *cbuf = '\0'; - return(savep = p, 1); - /* we'll be back for the rest... */ - } - - /* found end-of-string; can advance to next argument */ - return(savep = NULL, 1); - } - - if ((p = savep) == NULL) - return(-1); - - while((*++cbuf = *p++)) - if (*cbuf == '\\') - { - if ((*++cbuf = *p++) == '0') - return(savep = NULL, -1); - else - continue; - } - else if (*cbuf == '\n') - { - *cbuf = '\0'; - return(savep = p, 1); - } - - return(savep = NULL, 1); - } - - /* if no -e flag read from command file descriptor */ - while((inc = getc(cmdf)) != EOF) /* get next char */ - if ((*++cbuf = inc) == '\\') /* if it's escape */ - *++cbuf = inc = getc(cmdf); /* get next char */ - else if (*cbuf == '\n') /* end on newline */ - return(*cbuf = '\0', 1); /* cap the string */ - - return(*++cbuf = '\0', -1); /* end-of-file, no more chars */ -} - -/* expand an address at *cp... into expbuf, return ptr at following char */ -static char *address(char *expbuf) /* uses cp, linenum */ -{ - static int numl = 0; /* current ind in addr-number table */ - register char *rcp; /* temp compile ptr for forwd look */ - long lno; /* computed value of numeric address */ - - if (*cp == '$') /* end-of-source address */ - { - *expbuf++ = CEND; /* write symbolic end address */ - *expbuf++ = CEOF; /* and the end-of-address mark (!) */ - cp++; /* go to next source character */ - last_line_used = TRUE; - return(expbuf); /* we're done */ - } - if (*cp == '/') /* start of regular-expression match */ - return(recomp(expbuf, *cp++)); /* compile the RE */ - - rcp = cp; lno = 0; /* now handle a numeric address */ - while(*rcp >= '0' && *rcp <= '9') /* collect digits */ - lno = lno*10 + *rcp++ - '0'; /* compute their value */ - - if (rcp > cp) /* if we caught a number... */ - { - *expbuf++ = CLNUM; /* put a numeric-address marker */ - *expbuf++ = numl; /* and the address table index */ - linenum[numl++] = lno; /* and set the table entry */ - if (numl >= MAXLINES) /* oh-oh, address table overflow */ - die(TMLNR); /* abort with error message */ - *expbuf++ = CEOF; /* write the end-of-address marker */ - cp = rcp; /* point compile past the address */ - return(expbuf); /* we're done */ - } - - return(NULL); /* no legal address was found */ -} - -/* accept multiline input from *cp..., discarding leading whitespace - txp: where to put the text */ -static char *gettext(char* txp) /* uses global cp */ -{ - register char *p = cp; - - SKIPWS(p); /* discard whitespace */ - do { - if ((*txp = *p++) == '\\') /* handle escapes */ - *txp = *p++; - if (*txp == '\0') /* we're at end of input */ - return(cp = --p, ++txp); - else if (*txp == '\n') /* also SKIPWS after newline */ - SKIPWS(p); - } while (txp++); /* keep going till we find that nul */ - return(txp); -} - -/* find the label matching *ptr, return NULL if none */ -static label *search(label *ptr) /* uses global lablst */ -{ - register label *rp; - for(rp = lablst; rp < ptr; rp++) - if ((rp->name != NULL) && (strcmp(rp->name, ptr->name) == 0)) - return(rp); - return(NULL); -} - -/* write label links into the compiled-command space */ -static void resolve(void) /* uses global lablst */ -{ - register label *lptr; - register sedcmd *rptr, *trptr; - - /* loop through the label table */ - for(lptr = lablst; lptr < lab; lptr++) - if (lptr->address == NULL) /* barf if not defined */ - { - fprintf(stderr, ULABL, lptr->name); - exit(2); - } - else if (lptr->last) /* if last is non-null */ - { - rptr = lptr->last; /* chase it */ - while((trptr = rptr->u.link)) /* resolve refs */ - { - rptr->u.link = lptr->address; - rptr = trptr; - } - rptr->u.link = lptr->address; - } -} - -/* compile a y (transliterate) command - ep: where to compile to - delim: end delimiter to look for */ -static char *ycomp(char *ep, char delim) -{ - char *tp, *sp; - int c; - - /* scan the 'from' section for invalid chars */ - for(sp = tp = cp; *tp != delim; tp++) - { - if (*tp == '\\') - tp++; - if ((*tp == '\n') || (*tp == '\0')) - return(BAD); - } - tp++; /* tp now points at first char of 'to' section */ - - /* now rescan the 'from' section */ - while((c = *sp++ & 0x7F) != delim) - { - if (c == '\\' && *sp == 'n') - { - sp++; - c = '\n'; - } - if ((ep[c] = *tp++) == '\\' && *tp == 'n') - { - ep[c] = '\n'; - tp++; - } - if ((ep[c] == delim) || (ep[c] == '\0')) - return(BAD); - } - - if (*tp != delim) /* 'to', 'from' parts have unequal lengths */ - return(BAD); - - cp = ++tp; /* point compile ptr past translit */ - - for(c = 0; c < 128; c++) /* fill in self-map entries in table */ - if (ep[c] == 0) - ep[c] = c; - - return(ep + 0x80); /* return first free location past table end */ -} - -/* sedcomp.c ends here */ diff --git a/commands/sed/sedexec.c b/commands/sed/sedexec.c deleted file mode 100644 index 5088b7035..000000000 --- a/commands/sed/sedexec.c +++ /dev/null @@ -1,819 +0,0 @@ -/* sedexec.c -- axecute compiled form of stream editor commands - Copyright (C) 1995-2003 Eric S. Raymond - Copyright (C) 2004-2006 Rene Rebe - - The single entry point of this module is the function execute(). It -may take a string argument (the name of a file to be used as text) or -the argument NULL which tells it to filter standard input. It executes -the compiled commands in cmds[] on each line in turn. - The function command() does most of the work. match() and advance() -are used for matching text against precompiled regular expressions and -dosub() does right-hand-side substitution. Getline() does text input; -readout() and memcmp() are output and string-comparison utilities. -*/ - -#include /* exit */ -#include /* {f}puts, {f}printf, getc/putc, f{re}open, fclose */ -#include /* for isprint(), isdigit(), toascii() macros */ -#include /* for memcmp(3) */ -#include "sed.h" /* command type structures & miscellaneous constants */ - -/***** shared variables imported from the main ******/ - -/* main data areas */ -extern char linebuf[]; /* current-line buffer */ -extern sedcmd cmds[]; /* hold compiled commands */ -extern long linenum[]; /* numeric-addresses table */ - -/* miscellaneous shared variables */ -extern int nflag; /* -n option flag */ -extern int eargc; /* scratch copy of argument count */ -extern sedcmd *pending; /* ptr to command waiting to be executed */ - -extern int last_line_used; /* last line address ($) used */ - -/***** end of imported stuff *****/ - -#define MAXHOLD MAXBUF /* size of the hold space */ -#define GENSIZ MAXBUF /* maximum genbuf size */ - -static char LTLMSG[] = "sed: line too long\n"; - -static char *spend; /* current end-of-line-buffer pointer */ -static long lnum = 0L; /* current source line number */ - -/* append buffer maintenance */ -static sedcmd *appends[MAXAPPENDS]; /* array of ptrs to a,i,c commands */ -static sedcmd **aptr = appends; /* ptr to current append */ - -/* genbuf and its pointers */ -static char genbuf[GENSIZ]; -static char *loc1; -static char *loc2; -static char *locs; - -/* command-logic flags */ -static int lastline; /* do-line flag */ -static int line_with_newline; /* line had newline */ -static int jump; /* jump to cmd's link address if set */ -static int delete; /* delete command flag */ -static int needs_advance; /* needs inc after substitution */ - /* ugly HACK - neds REWORK */ - -/* tagged-pattern tracking */ -static char *bracend[MAXTAGS]; /* tagged pattern start pointers */ -static char *brastart[MAXTAGS]; /* tagged pattern end pointers */ - -/* prototypes */ -static char *getline(char *buf, int max); -static char *place(char* asp, char* al1, char* al2); -static int advance(char* lp, char* ep, char** eob); -static int match(char *expbuf, int gf); -static int selected(sedcmd *ipc); -static int substitute(sedcmd *ipc); -static void command(sedcmd *ipc); -static void dosub(char *rhsbuf); -static void dumpto(char *p1, FILE *fp); -static void listto(char *p1, FILE *fp); -static void readout(void); -static void truncated(int h); - -/* execute the compiled commands in cmds[] on a file - file: name of text source file to be filtered */ -void execute(char* file) -{ - register sedcmd *ipc; /* ptr to current command */ - char *execp; /* ptr to source */ - - if (file != NULL) /* filter text from a named file */ - if (freopen(file, "r", stdin) == NULL) - fprintf(stderr, "sed: can't open %s\n", file); - - if (pending) /* there's a command waiting */ - { - ipc = pending; /* it will be first executed */ - pending = FALSE; /* turn off the waiting flag */ - goto doit; /* go to execute it immediately */ - } - - /* here's the main command-execution loop */ - for(;;) - { - /* get next line to filter */ - if ((execp = getline(linebuf, MAXBUF+1)) == BAD) - return; - spend = execp; - - /* loop through compiled commands, executing them */ - for(ipc = cmds; ipc->command; ) - { - /* address command to select? - If not address - but allbut then invert, that is skip, the commmand */ - if (ipc->addr1 || ipc->flags.allbut) { - if (!ipc->addr1 || !selected(ipc)) { - ipc++; /* not selected, next cmd */ - continue; - } - } - doit: - command(ipc); /* execute the command pointed at */ - - if (delete) /* if delete flag is set */ - break; /* don't exec rest of compiled cmds */ - - if (jump) /* if jump set, follow cmd's link */ - { - jump = FALSE; - if ((ipc = ipc->u.link) == 0) - { - ipc = cmds; - break; - } - } - else /* normal goto next command */ - ipc++; - } - /* we've now done all modification commands on the line */ - - /* here's where the transformed line is output */ - if (!nflag && !delete) - { - fwrite(linebuf, spend - linebuf, 1, stdout); - if (line_with_newline) - putc('\n', stdout); - } - - /* if we've been set up for append, emit the text from it */ - if (aptr > appends) - readout(); - - delete = FALSE; /* clear delete flag; about to get next cmd */ - } -} - -/* is current command selected */ -static int selected(sedcmd *ipc) -{ - register char *p1 = ipc->addr1; /* point p1 at first address */ - register char *p2 = ipc->addr2; /* and p2 at second */ - unsigned char c; - int selected = FALSE; - - if (ipc->flags.inrange) - { - selected = TRUE; - if (*p2 == CEND) - ; - else if (*p2 == CLNUM) - { - c = p2[1]; - if (lnum >= linenum[c]) - ipc->flags.inrange = FALSE; - } - else if (match(p2, 0)) - ipc->flags.inrange = FALSE; - } - else if (*p1 == CEND) - { - if (lastline) - selected = TRUE; - } - else if (*p1 == CLNUM) - { - c = p1[1]; - if (lnum == linenum[c]) { - selected = TRUE; - if (p2) - ipc->flags.inrange = TRUE; - } - } - else if (match(p1, 0)) - { - selected = TRUE; - if (p2) - ipc->flags.inrange = TRUE; - } - return ipc->flags.allbut ? !selected : selected; -} - -/* match RE at expbuf against linebuf; if gf set, copy linebuf from genbuf */ -static int match(char *expbuf, int gf) /* uses genbuf */ -{ - char *p1, *p2, c; - - if (gf) - { - if (*expbuf) - return(FALSE); - p1 = linebuf; p2 = genbuf; - while ((*p1++ = *p2++)); - if (needs_advance) { - loc2++; - } - locs = p1 = loc2; - } - else - { - p1 = linebuf + needs_advance; - locs = FALSE; - } - needs_advance = 0; - - p2 = expbuf; - if (*p2++) - { - loc1 = p1; - if(*p2 == CCHR && p2[1] != *p1) /* 1st char is wrong */ - return(FALSE); /* so fail */ - return(advance(p1, p2, NULL)); /* else try to match rest */ - } - - /* quick check for 1st character if it's literal */ - if (*p2 == CCHR) - { - c = p2[1]; /* pull out character to search for */ - do { - if (*p1 != c) - continue; /* scan the source string */ - if (advance(p1, p2,NULL)) /* found it, match the rest */ - return(loc1 = p1, 1); - } while - (*p1++); - return(FALSE); /* didn't find that first char */ - } - - /* else try for unanchored match of the pattern */ - do { - if (advance(p1, p2, NULL)) - return(loc1 = p1, 1); - } while - (*p1++); - - /* if got here, didn't match either way */ - return(FALSE); -} - -/* attempt to advance match pointer by one pattern element - lp: source (linebuf) ptr - ep: regular expression element ptr */ -static int advance(char* lp, char* ep, char** eob) -{ - char *curlp; /* save ptr for closures */ - char c; /* scratch character holder */ - char *bbeg; - int ct; - signed int bcount = -1; - - for (;;) - switch (*ep++) - { - case CCHR: /* literal character */ - if (*ep++ == *lp++) /* if chars are equal */ - continue; /* matched */ - return(FALSE); /* else return false */ - - case CDOT: /* anything but newline */ - if (*lp++) /* first NUL is at EOL */ - continue; /* keep going if didn't find */ - return(FALSE); /* else return false */ - - case CNL: /* start-of-line */ - case CDOL: /* end-of-line */ - if (*lp == 0) /* found that first NUL? */ - continue; /* yes, keep going */ - return(FALSE); /* else return false */ - - case CEOF: /* end-of-address mark */ - loc2 = lp; /* set second loc */ - return(TRUE); /* return true */ - - case CCL: /* a closure */ - c = *lp++ & 0177; - if (ep[c>>3] & bits(c & 07)) /* is char in set? */ - { - ep += 16; /* then skip rest of bitmask */ - continue; /* and keep going */ - } - return(FALSE); /* else return false */ - - case CBRA: /* start of tagged pattern */ - brastart[(unsigned char)*ep++] = lp; /* mark it */ - continue; /* and go */ - - case CKET: /* end of tagged pattern */ - bcount = *ep; - if (eob) { - *eob = lp; - return (TRUE); - } - else - bracend[(unsigned char)*ep++] = lp; /* mark it */ - continue; /* and go */ - - case CBACK: /* match back reference */ - bbeg = brastart[(unsigned char)*ep]; - ct = bracend[(unsigned char)*ep++] - bbeg; - - if (memcmp(bbeg, lp, ct) == 0) - { - lp += ct; - continue; - } - return(FALSE); - - case CBRA|STAR: /* \(...\)* */ - { - char *lastlp; - curlp = lp; - - if (*ep > bcount) - brastart[(unsigned char)*ep] = bracend[(unsigned char)*ep] = lp; - - while (advance(lastlp=lp, ep+1, &lp)) { - if (*ep > bcount && lp != lastlp) { - bracend[(unsigned char)*ep] = lp; /* mark it */ - brastart[(unsigned char)*ep] = lastlp; - } - if (lp == lastlp) break; - } - ep++; - - /* FIXME: scan for the brace end */ - while (*ep != CKET) - ep++; - ep+=2; - - needs_advance = 1; - if (lp == curlp) /* 0 matches */ - continue; - lp++; - goto star; - } - case CBACK|STAR: /* \n* */ - bbeg = brastart[(unsigned char)*ep]; - ct = bracend[(unsigned char)*ep++] - bbeg; - curlp = lp; - while(memcmp(bbeg, lp, ct) == 0) - lp += ct; - - while(lp >= curlp) - { - if (advance(lp, ep, eob)) - return(TRUE); - lp -= ct; - } - return(FALSE); - - case CDOT|STAR: /* match .* */ - curlp = lp; /* save closure start loc */ - while (*lp++); /* match anything */ - goto star; /* now look for followers */ - - case CCHR|STAR: /* match * */ - curlp = lp; /* save closure start loc */ - while (*lp++ == *ep); /* match many of that char */ - ep++; /* to start of next element */ - goto star; /* match it and followers */ - - case CCL|STAR: /* match [...]* */ - curlp = lp; /* save closure start loc */ - do { - c = *lp++ & 0x7F; /* match any in set */ - } while - (ep[c>>3] & bits(c & 07)); - ep += 16; /* skip past the set */ - goto star; /* match followers */ - - star: /* the recursion part of a * or + match */ - needs_advance = 1; - if (--lp == curlp) { /* 0 matches */ - continue; - } -#if 0 - if (*ep == CCHR) - { - c = ep[1]; - do { - if (*lp != c) - continue; - if (advance(lp, ep, eob)) - return(TRUE); - } while - (lp-- > curlp); - return(FALSE); - } - - if (*ep == CBACK) - { - c = *(brastart[ep[1]]); - do { - if (*lp != c) - continue; - if (advance(lp, ep, eob)) - return(TRUE); - } while - (lp-- > curlp); - return(FALSE); - } -#endif - /* match followers, try shorter match, if needed */ - do { - if (lp == locs) - break; - if (advance(lp, ep, eob)) - return(TRUE); - } while - (lp-- > curlp); - return(FALSE); - - default: - fprintf(stderr, "sed: internal RE error, %o\n", *--ep); - exit (2); - } -} - -/* perform s command - ipc: ptr to s command struct */ -static int substitute(sedcmd *ipc) -{ - unsigned int n = 1; - /* find a match */ - /* the needs_advance code got a bit tricky - might needs a clean - refactoring */ - while (match(ipc->u.lhs, 0)) { - /* nth 0 is implied 1 */ - if (!ipc->nth || n == ipc->nth) { - dosub(ipc->rhs); /* perform it once */ - n++; /* mark for return */ - break; - } - needs_advance = n++; - } - if (n == 1) - return(FALSE); /* command fails */ - - if (ipc->flags.global) /* if global flag enabled */ - do { /* cycle through possibles */ - if (match(ipc->u.lhs, 1)) { /* found another */ - dosub(ipc->rhs); /* so substitute */ - } - else /* otherwise, */ - break; /* we're done */ - } while (*loc2); - return(TRUE); /* we succeeded */ -} - -/* generate substituted right-hand side (of s command) - rhsbuf: where to put the result */ -static void dosub(char *rhsbuf) /* uses linebuf, genbuf, spend */ -{ - char *lp, *sp, *rp; - int c; - - /* copy linebuf to genbuf up to location 1 */ - lp = linebuf; sp = genbuf; - while (lp < loc1) *sp++ = *lp++; - - for (rp = rhsbuf; (c = *rp++); ) - { - if (c & 0200 && (c & 0177) == '0') - { - sp = place(sp, loc1, loc2); - continue; - } - else if (c & 0200 && (c &= 0177) >= '1' && c < MAXTAGS+'1') - { - sp = place(sp, brastart[c-'1'], bracend[c-'1']); - continue; - } - *sp++ = c & 0177; - if (sp >= genbuf + MAXBUF) - fprintf(stderr, LTLMSG); - - } - lp = loc2; - loc2 = sp - genbuf + linebuf; - while ((*sp++ = *lp++)) - if (sp >= genbuf + MAXBUF) - fprintf(stderr, LTLMSG); - lp = linebuf; sp = genbuf; - while ((*lp++ = *sp++)); - spend = lp-1; -} - -/* place chars at *al1...*(al1 - 1) at asp... in genbuf[] */ -static char *place(char* asp, char* al1, char* al2) /* uses genbuf */ -{ - while (al1 < al2) - { - *asp++ = *al1++; - if (asp >= genbuf + MAXBUF) - fprintf(stderr, LTLMSG); - } - return(asp); -} - -/* list the pattern space in visually unambiguous form *p1... to fp - p1: the source - fp: output stream to write to */ -static void listto(char *p1, FILE *fp) -{ - for (; p1command) - { - case ACMD: /* append */ - *aptr++ = ipc; - if (aptr >= appends + MAXAPPENDS) - fprintf(stderr, - "sed: too many appends after line %ld\n", - lnum); - *aptr = 0; - break; - - case CCMD: /* change pattern space */ - delete = TRUE; - if (!ipc->flags.inrange || lastline) - printf("%s\n", ipc->u.lhs); - break; - - case DCMD: /* delete pattern space */ - delete++; - break; - - case CDCMD: /* delete a line in hold space */ - p1 = p2 = linebuf; - while(*p1 != '\n') - if ((delete = (*p1++ == 0))) - return; - p1++; - while((*p2++ = *p1++)) continue; - spend = p2-1; - jump++; - break; - - case EQCMD: /* show current line number */ - fprintf(stdout, "%ld\n", lnum); - break; - - case GCMD: /* copy hold space to pattern space */ - p1 = linebuf; p2 = holdsp; while((*p1++ = *p2++)); - spend = p1-1; - break; - - case CGCMD: /* append hold space to pattern space */ - *spend++ = '\n'; - p1 = spend; p2 = holdsp; - do { - if (p1 > linebuf + MAXBUF) { - truncated(FALSE); - p1[-1] = 0; - break; - } - } while((*p1++ = *p2++)); - - spend = p1-1; - break; - - case HCMD: /* copy pattern space to hold space */ - p1 = holdsp; p2 = linebuf; while((*p1++ = *p2++)); - hspend = p1-1; - break; - - case CHCMD: /* append pattern space to hold space */ - *hspend++ = '\n'; - p1 = hspend; p2 = linebuf; - do { - if (p1 > holdsp + MAXBUF) { - truncated(TRUE); - p1[-1] = 0; - break; - } - } while((*p1++ = *p2++)); - - hspend = p1-1; - break; - - case ICMD: /* insert text */ - printf("%s\n", ipc->u.lhs); - break; - - case BCMD: /* branch to label */ - jump = TRUE; - break; - - case LCMD: /* list text */ - listto(linebuf, (ipc->fout != NULL)?ipc->fout:stdout); break; - - case CLCMD: /* dump text */ - dumpto(linebuf, (ipc->fout != NULL)?ipc->fout:stdout); break; - - case NCMD: /* read next line into pattern space */ - if (!nflag) - puts(linebuf); /* flush out the current line */ - if (aptr > appends) - readout(); /* do pending a, r commands */ - if ((execp = getline(linebuf, MAXBUF+1)) == BAD) - { - pending = ipc; - delete = TRUE; - break; - } - spend = execp; - break; - - case CNCMD: /* append next line to pattern space */ - if (aptr > appends) - readout(); - *spend++ = '\n'; - if ((execp = getline(spend, - linebuf + MAXBUF+1 - spend)) == BAD) - { - pending = ipc; - delete = TRUE; - break; - } - spend = execp; - break; - - case PCMD: /* print pattern space */ - puts(linebuf); - break; - - case CPCMD: /* print one line from pattern space */ - cpcom: /* so s command can jump here */ - for(p1 = linebuf; *p1 != '\n' && *p1 != '\0'; ) - putc(*p1++, stdout); - putc('\n', stdout); - break; - - case QCMD: /* quit the stream editor */ - if (!nflag) - puts(linebuf); /* flush out the current line */ - if (aptr > appends) - readout(); /* do any pending a and r commands */ - exit(0); - - case RCMD: /* read a file into the stream */ - *aptr++ = ipc; - if (aptr >= appends + MAXAPPENDS) - fprintf(stderr, - "sed: too many reads after line %ld\n", - lnum); - *aptr = 0; - break; - - case SCMD: /* substitute RE */ - didsub = substitute(ipc); - if (ipc->flags.print && didsub) - { - if (ipc->flags.print == TRUE) - puts(linebuf); - else - goto cpcom; - } - if (didsub && ipc->fout) - fprintf(ipc->fout, "%s\n", linebuf); - break; - - case TCMD: /* branch on last s successful */ - case CTCMD: /* branch on last s failed */ - if (didsub == (ipc->command == CTCMD)) - break; /* no branch if last s failed, else */ - didsub = FALSE; - jump = TRUE; /* set up to jump to assoc'd label */ - break; - - case CWCMD: /* write one line from pattern space */ - for(p1 = linebuf; *p1 != '\n' && *p1 != '\0'; ) - putc(*p1++, ipc->fout); - putc('\n', ipc->fout); - break; - - case WCMD: /* write pattern space to file */ - fprintf(ipc->fout, "%s\n", linebuf); - break; - - case XCMD: /* exchange pattern and hold spaces */ - p1 = linebuf; p2 = genbuf; while((*p2++ = *p1++)) continue; - p1 = holdsp; p2 = linebuf; while((*p2++ = *p1++)) continue; - spend = p2 - 1; - p1 = genbuf; p2 = holdsp; while((*p2++ = *p1++)) continue; - hspend = p2 - 1; - break; - - case YCMD: - p1 = linebuf; p2 = ipc->u.lhs; - while((*p1 = p2[(unsigned char)*p1])) - p1++; - break; - } -} - -/* get next line of text to be filtered - buf: where to send the input - max: max chars to read */ -static char *getline(char *buf, int max) -{ - if (fgets(buf, max, stdin) != NULL) - { - int c; - - lnum++; /* note that we got another line */ - /* find the end of the input and overwrite a possible '\n' */ - while (*buf != '\n' && *buf != 0) - buf++; - line_with_newline = *buf == '\n'; - *buf=0; - - /* detect last line - but only if the address was used in a command */ - if (last_line_used) { - if ((c = fgetc(stdin)) != EOF) - ungetc (c, stdin); - else { - if (eargc == 0) /* if no more args */ - lastline = TRUE; /* set a flag */ - } - } - - return(buf); /* return ptr to terminating null */ - } - else - { - return(BAD); - } -} - -/* write file indicated by r command to output */ -static void readout(void) -{ - register int t; /* hold input char or EOF */ - FILE *fi; /* ptr to file to be read */ - - aptr = appends - 1; /* arrange for pre-increment to work right */ - while(*++aptr) - if ((*aptr)->command == ACMD) /* process "a" cmd */ - printf("%s\n", (*aptr)->u.lhs); - else /* process "r" cmd */ - { - if ((fi = fopen((*aptr)->u.lhs, "r")) == NULL) - continue; - while((t = getc(fi)) != EOF) - putc((char) t, stdout); - fclose(fi); - } - aptr = appends; /* reset the append ptr */ - *aptr = 0; -} - -/* sedexec.c ends here */ -- 2.44.0