⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 man2html.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include "httpd.h"#include "httpsrv.h"static	Hio		*hout;static	Hio		houtb;static	HConnect	*connect;void	doconvert(char*, int);voiderror(char *title, char *fmt, ...){	va_list arg;	char buf[1024], *out;	va_start(arg, fmt);	out = vseprint(buf, buf+sizeof(buf), fmt, arg);	va_end(arg);	*out = 0;	hprint(hout, "%s 404 %s\n", hversion, title);	hprint(hout, "Date: %D\n", time(nil));	hprint(hout, "Server: Plan9\n");	hprint(hout, "Content-type: text/html\n");	hprint(hout, "\n");	hprint(hout, "<head><title>%s</title></head>\n", title);	hprint(hout, "<body><h1>%s</h1></body>\n", title);	hprint(hout, "%s\n", buf);	hflush(hout);	writelog(connect, "Reply: 404\nReason: %s\n", title);	exits(nil);}typedef struct Hit	Hit;struct Hit {	Hit *next;	char *file;};voidlookup(char *object, int section, Hit **list){	int fd;	char *p, *f;	Biobuf b;	char file[256];	Hit *h;	while(*list != nil)		list = &(*list)->next;	snprint(file, sizeof(file), "/sys/man/%d/INDEX", section);	fd = open(file, OREAD);	if(fd > 0){		Binit(&b, fd, OREAD);		for(;;){			p = Brdline(&b, '\n');			if(p == nil)				break;			p[Blinelen(&b)-1] = 0;			f = strchr(p, ' ');			if(f == nil)				continue;			*f++ = 0;			if(strcmp(p, object) == 0){				h = ezalloc(sizeof *h);				*list = h;				h->next = nil;				snprint(file, sizeof(file), "/%d/%s", section, f);				h->file = estrdup(file);				close(fd);				return;			}		}		close(fd);	}	snprint(file, sizeof(file), "/sys/man/%d/%s", section, object);	if(access(file, 0) == 0){		h = ezalloc(sizeof *h);		*list = h;		h->next = nil;		h->file = estrdup(file+8);	}}voidmanindex(int sect, int vermaj){	int i;	if(vermaj){		hokheaders(connect);		hprint(hout, "Content-type: text/html\r\n");		hprint(hout, "\r\n");	}	hprint(hout, "<head><title>plan 9 section index");	if(sect)		hprint(hout, "(%d)\n", sect);	hprint(hout, "</title></head><body>\n");	hprint(hout, "<H6>Section Index");	if(sect)		hprint(hout, "(%d)\n", sect);	hprint(hout, "</H6>\n");	if(sect)		hprint(hout, "<p><a href=\"/plan9/man%d.html\">/plan9/man%d.html</a>\n",			sect, sect);	else for(i = 1; i < 10; i++)		hprint(hout, "<p><a href=\"/plan9/man%d.html\">/plan9/man%d.html</a>\n",			i, i);	hprint(hout, "</body>\n");}voidman(char *o, int sect, int vermaj){	int i;	Hit *list;	list = nil;	if(*o == 0){		manindex(sect, vermaj);		return;	}	if(sect > 0 && sect < 10)		lookup(o, sect, &list);	else		for(i = 1; i < 9; i++)			lookup(o, i, &list);	if(list != nil && list->next == nil){		doconvert(list->file, vermaj);		return;	}	if(vermaj){		hokheaders(connect);		hprint(hout, "Content-type: text/html\r\n");		hprint(hout, "\r\n");	}	hprint(hout, "<head><title>plan 9 man %H", o);	if(sect)		hprint(hout, "(%d)\n", sect);	hprint(hout, "</title></head><body>\n");	hprint(hout, "<H6>Search for %H", o);	if(sect)		hprint(hout, "(%d)\n", sect);	hprint(hout, "</H6>\n");	for(; list; list = list->next)		hprint(hout, "<p><a href=\"/magic/man2html%U\">/magic/man2html%H</a>\n",			list->file, list->file);	hprint(hout, "</body>\n");}voidstrlwr(char *p){	for(; *p; p++)		if('A' <= *p && *p <= 'Z')			*p += 'a'-'A';}voidredirectto(char *uri){	if(connect){		hmoved(connect, uri);		exits(0);	}else		hprint(hout, "Your selection moved to <a href=\"%U\"> here</a>.<p></body>\r\n", uri);}voidsearchfor(char *search){	int i, j, n, fd;	char *p, *sp;	Biobufhdr *b;	char *arg[32];	hprint(hout, "<head><title>plan 9 search for %H</title></head>\n", search);	hprint(hout, "<body>\n");	hprint(hout, "<p>This is a keyword search through Plan 9 man pages.\n");	hprint(hout, "The search is case insensitive; blanks denote \"boolean and\".\n");	hprint(hout, "<FORM METHOD=\"GET\" ACTION=\"/magic/man2html\">\n");	hprint(hout, "<INPUT NAME=\"pat\" TYPE=\"text\" SIZE=\"60\">\n");	hprint(hout, "<INPUT TYPE=\"submit\" VALUE=\"Submit\">\n");	hprint(hout, "</FORM>\n");	hprint(hout, "<hr><H6>Search for %H</H6>\n", search);	n = getfields(search, arg, 32, 1, "+");	for(i = 0; i < n; i++){		for(j = i+1; j < n; j++){			if(strcmp(arg[i], arg[j]) > 0){				sp = arg[j];				arg[j] = arg[i];				arg[i] = sp;			}		}		sp = malloc(strlen(arg[i]) + 2);		if(sp != nil){			strcpy(sp+1, arg[i]);			sp[0] = ' ';			arg[i] = sp;		}	}	/*	 *  search index till line starts alphabetically < first token	 */	fd = open("/sys/man/searchindex", OREAD);	if(fd < 0){		hprint(hout, "<body>error: No Plan 9 search index\n");		hprint(hout, "</body>");		return;	}	p = malloc(32*1024);	if(p == nil){		close(fd);		return;	}	b = ezalloc(sizeof *b);	Binits(b, fd, OREAD, (uchar*)p, 32*1024);	for(;;){		p = Brdline(b, '\n');		if(p == nil)			break;		p[Blinelen(b)-1] = 0;		for(i = 0; i < n; i++){			sp = strstr(p, arg[i]);			if(sp == nil)				break;			p = sp;		}		if(i < n)			continue;		sp = strrchr(p, '\t');		if(sp == nil)			continue;		sp++;		hprint(hout, "<p><a href=\"/magic/man2html/%U\">/magic/man2html/%H</a>\n",			sp, sp);	}	hprint(hout, "</body>");	Bterm(b);	free(b);	free(p);	close(fd);}/* *  find man pages mentioning the search string */voiddosearch(int vermaj, char *search){	int sect;	char *p;	if(strncmp(search, "man=", 4) == 0){		sect = 0;		search = hurlunesc(connect, search+4);		p = strchr(search, '&');		if(p != nil){			*p++ = 0;			if(strncmp(p, "sect=", 5) == 0)				sect = atoi(p+5);		}		man(search, sect, vermaj);		return;	}	if(vermaj){		hokheaders(connect);		hprint(hout, "Content-type: text/html\r\n");		hprint(hout, "\r\n");	}	if(strncmp(search, "pat=", 4) == 0){		search = hurlunesc(connect, search+4);		search = hlower(search);		searchfor(search);		return;	}	hprint(hout, "<head><title>illegal search</title></head>\n");	hprint(hout, "<body><p>Illegally formatted Plan 9 man page search</p>\n");	search = hurlunesc(connect, search);	hprint(hout, "<body><p>%H</p>\n", search);	hprint(hout, "</body>");}/* *  convert a man page to html and output */voiddoconvert(char *uri, int vermaj){	char *p;	char file[256];	char title[256];	char err[ERRMAX];	int pfd[2];	Dir *d;	Waitmsg *w;	int x;	if(strstr(uri, ".."))		error("bad URI", "man page URI cannot contain ..");	p = strstr(uri, "/intro");	if(p == nil){		while(*uri == '/')			uri++;		/* redirect section requests */		snprint(file, sizeof(file), "/sys/man/%s", uri);		d = dirstat(file);		if(d == nil){			strlwr(file);			if(dirstat(file) != nil){				snprint(file, sizeof(file), "/magic/man2html/%s", uri);				strlwr(file);				redirectto(file);			}			error(uri, "man page not found");		}		x = d->qid.type;		free(d);		if(x & QTDIR){			if(*uri == 0 || strcmp(uri, "/") == 0)				redirectto("/sys/man/index.html");			else {				snprint(file, sizeof(file), "/sys/man/%s/INDEX.html",					uri+1);				redirectto(file);			}			return;		}	} else {		/* rewrite the name intro */		*p = 0;		snprint(file, sizeof(file), "/sys/man/%s/0intro", uri);		d = dirstat(file);		free(d);		if(d == nil)			error(uri, "man page not found");	}	if(vermaj){		hokheaders(connect);		hprint(hout, "Content-type: text/html\r\n");		hprint(hout, "\r\n");	}	hflush(hout);	if(pipe(pfd) < 0)		error("out of resources", "pipe failed");	/* troff -manhtml <file> | troff2html -t '' */	switch(fork()){	case -1:		error("out of resources", "fork failed");	case 0:		snprint(title, sizeof(title), "Plan 9 %s", file);		close(0);		dup(pfd[0], 0);		close(pfd[0]);		close(pfd[1]);		execl("/bin/troff2html", "troff2html", "-t", title, nil);		errstr(err, sizeof err);		exits(err);	}	switch(fork()){	case -1:		error("out of resources", "fork failed");	case 0:		snprint(title, sizeof(title), "Plan 9 %s", file);		close(0);		close(1);		dup(pfd[1], 1);		close(pfd[0]);		close(pfd[1]);		execl("/bin/troff", "troff", "-manhtml", file, nil);		errstr(err, sizeof err);		exits(err);	}	close(pfd[0]);	close(pfd[1]);	/* wait for completion */	for(;;){		w = wait();		if(w == nil)			break;		if(w->msg[0] != 0)			print("whoops %s\n", w->msg);		free(w);	}}voidmain(int argc, char **argv){	fmtinstall('H', httpfmt);	fmtinstall('U', hurlfmt);	if(argc == 2){		hinit(&houtb, 1, Hwrite);		hout = &houtb;		doconvert(argv[1], 0);		exits(nil);	}	close(2);	connect = init(argc, argv);	hout = &connect->hout;	if(hparseheaders(connect, HSTIMEOUT) < 0)		exits("failed");	if(strcmp(connect->req.meth, "GET") != 0 && strcmp(connect->req.meth, "HEAD") != 0){		hunallowed(connect, "GET, HEAD");		exits("not allowed");	}	if(connect->head.expectother || connect->head.expectcont){		hfail(connect, HExpectFail, nil);		exits("failed");	}	bind("/usr/web/sys/man", "/sys/man", MREPL);	if(connect->req.search != nil)		dosearch(connect->req.vermaj, connect->req.search);	else		doconvert(connect->req.uri, connect->req.vermaj);	hflush(hout);	writelog(connect, "200 man2html %ld %ld\n", hout->seek, hout->seek);	exits(nil);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -