diff options
-rw-r--r-- | web/.cvsignore | 3 | ||||
-rw-r--r-- | web/Makefile | 6 | ||||
-rw-r--r-- | web/Makefile.old | 120 | ||||
-rw-r--r-- | web/Makefile.tmpl | 16 | ||||
-rw-r--r-- | web/Makefile.tmpl.bak | 17 | ||||
-rwxr-xr-x | web/args.c | 228 | ||||
-rw-r--r-- | web/board.c | 39 | ||||
-rw-r--r-- | web/chmod | 1 | ||||
-rwxr-xr-x | web/l | 1 | ||||
-rw-r--r-- | web/mail.c | 6 | ||||
-rw-r--r-- | web/mod_ptt.c | 284 | ||||
-rw-r--r-- | web/mod_ptt.h | 13 | ||||
-rwxr-xr-x | web/mytime.h | 189 | ||||
-rwxr-xr-x | web/parse_html.c | 294 | ||||
-rw-r--r-- | web/post.c | 6 | ||||
-rwxr-xr-x | web/r | 1 | ||||
-rwxr-xr-x | web/s | 1 | ||||
-rwxr-xr-x | web/stuff.c | 269 | ||||
-rwxr-xr-x | web/t | 1 | ||||
-rw-r--r-- | web/user.c | 6 |
20 files changed, 1501 insertions, 0 deletions
diff --git a/web/.cvsignore b/web/.cvsignore new file mode 100644 index 00000000..33ec1741 --- /dev/null +++ b/web/.cvsignore @@ -0,0 +1,3 @@ +*.o +*.so +*.a diff --git a/web/Makefile b/web/Makefile new file mode 100644 index 00000000..095610b3 --- /dev/null +++ b/web/Makefile @@ -0,0 +1,6 @@ +all: mod_ptt.c mod_ptt.h + apxs -I ../include -c mod_ptt.c ../util/util_cache.c ../util/util_passwd.c ../util/util_record.c + cp mod_ptt.so /usr/local/libexec/apache/mod_ptt.so + chmod 775 /usr/local/libexec/apache/mod_ptt.so +clean: + rm -f *.o *.a *.so diff --git a/web/Makefile.old b/web/Makefile.old new file mode 100644 index 00000000..db2735bf --- /dev/null +++ b/web/Makefile.old @@ -0,0 +1,120 @@ +## +## Apache Makefile, automatically generated by Configure script. +## Hand-edited changes will be lost if the Configure script is re-run. +## Sources: - ../../Makefile.config (via Configuration) +## - ./Makefile.tmpl +## + +## +## Inherited Makefile options from Configure script +## (Begin of automatically generated section) +## +SRCDIR=../.. +EXTRA_CFLAGS= +EXTRA_LDFLAGS= +EXTRA_LIBS= +EXTRA_INCLUDES= +EXTRA_DEPS= +OSDIR=$(SRCDIR)/os/unix +INCDIR=$(SRCDIR)/include +INCLUDES0=-I$(OSDIR) -I$(INCDIR) -I../$(INCDIR) +SHELL=/bin/sh +OS=FreeBSD 4.6 +CC=gcc +CPP=gcc -E +TARGET=httpd +OPTIM= +CFLAGS1= -funsigned-char -DUSE_EXPAT -I$(SRCDIR)/lib/expat-lite -DNO_DL_NEEDED +INCLUDES1= +LIBS_SHLIB= +LDFLAGS1= +MFLAGS_STATIC= +REGLIB= +EXPATLIB=lib/expat-lite/libexpat.a +RANLIB=ranlib +LIBS1= -lcrypt +## +## (End of automatically generated section) +## + +## +## Default Makefile options from Configure script +## (Begin of automatically generated section) +## +CFLAGS=$(OPTIM) $(CFLAGS1) $(EXTRA_CFLAGS) +LIBS=$(EXTRA_LIBS) $(LIBS1) +INCLUDES=$(INCLUDES1) $(INCLUDES0) $(EXTRA_INCLUDES) +LDFLAGS=$(LDFLAGS1) $(EXTRA_LDFLAGS) +INCDIR=$(SRCDIR)/include +OBJS=mod_ptt.o parse_html.o +BBSLIBS=util_cache.o util_passwd.o util_record.o +LIB=libptt.a +SHLIBS= +OBJS_PIC= + +all: lib shlib + +lib: $(LIB) + +shlib: $(SHLIBS) + +dummy $(LIB): $(OBJS) + rm -f $@ + ar cr $@ $(OBJS) $(BBSLIBS) + $(RANLIB) $@ + +.SUFFIXES: .o .so .dll + +.c.o: + $(CC) -c $(INCLUDES) $(CFLAGS) $< + +.c.so: + $(CC) -c $(INCLUDES) $(CFLAGS) $(CFLAGS_SHLIB) $< && mv $*.o $*.lo + $(LD_SHLIB) $(LDFLAGS_SHLIB) -o $@ $*.lo $(LIBS_SHLIB) + +clean: + rm -f $(LIB) $(OBJS) $(SHLIBS) $(OBJS_PIC) + +distclean: clean + rm -f Makefile + +# NOT FOR END USERS! +depend: + cp Makefile.tmpl Makefile.tmpl.bak \ + && sed -ne '1,/^# DO NOT REMOVE/p' Makefile.tmpl > Makefile.new \ + && gcc -MM $(INCLUDES) $(CFLAGS) *.c >> Makefile.new \ + && sed -e '1,$$s: $(INCDIR)/: $$(INCDIR)/:g' \ + -e '1,$$s: $(OSDIR)/: $$(OSDIR)/:g' Makefile.new \ + > Makefile.tmpl \ + && rm Makefile.new + +## +## (End of automatically generated section) +## + +#Dependencies + +$(OBJS) $(OBJS_PIC): Makefile + +# DO NOT REMOVE +mod_ptt.o: mod_ptt.c $(INCDIR)/httpd.h \ + $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ + $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ + $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h \ + $(INCDIR)/ap_alloc.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ + $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ + $(INCDIR)/http_core.h $(INCDIR)/http_log.h \ + $(INCDIR)/http_main.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/util_script.h \ + /home/bbs/pttbbs/include/bbs.h + +parse_html.o: parse_html.c $(INCDIR)/httpd.h \ + $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ + $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ + $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h \ + $(INCDIR)/ap_alloc.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ + $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ + $(INCDIR)/http_core.h $(INCDIR)/http_log.h \ + $(INCDIR)/http_main.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/util_script.h \ + /home/bbs/pttbbs/include/bbs.h diff --git a/web/Makefile.tmpl b/web/Makefile.tmpl new file mode 100644 index 00000000..83ed1e84 --- /dev/null +++ b/web/Makefile.tmpl @@ -0,0 +1,16 @@ + +#Dependencies + +$(OBJS) $(OBJS_PIC): Makefile + +BBSLIBS= util_cache.o util_record.o util_passwd.o + +# DO NOT REMOVE +mod_ptt.o: mod_ptt.c $(INCDIR)/httpd.h $(INCDIR)/ap_config.h \ + $(INCDIR)/ap_mmn.h $(INCDIR)/ap_config_auto.h \ + $(OSDIR)/os.h $(OSDIR)/os-inline.c $(INCDIR)/ap_ctype.h \ + $(INCDIR)/ap_alloc.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ + $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ + $(INCDIR)/http_core.h $(INCDIR)/http_log.h \ + $(INCDIR)/http_main.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/util_script.h diff --git a/web/Makefile.tmpl.bak b/web/Makefile.tmpl.bak new file mode 100644 index 00000000..e686b7a9 --- /dev/null +++ b/web/Makefile.tmpl.bak @@ -0,0 +1,17 @@ + +#Dependencies + +$(OBJS) $(OBJS_PIC): Makefile + +BBSLIBS= util_cache.o util_record.o util_passwd.o + +# DO NOT REMOVE +mod_ptt.o: mod_ptt.c $(INCDIR)/httpd.h \ + $(INCDIR)/ap_config.h $(INCDIR)/ap_mmn.h \ + $(INCDIR)/ap_config_auto.h $(OSDIR)/os.h \ + $(INCDIR)/ap_ctype.h $(INCDIR)/hsregex.h \ + $(INCDIR)/ap_alloc.h $(INCDIR)/buff.h $(INCDIR)/ap.h \ + $(INCDIR)/util_uri.h $(INCDIR)/http_config.h \ + $(INCDIR)/http_core.h $(INCDIR)/http_log.h \ + $(INCDIR)/http_main.h $(INCDIR)/http_protocol.h \ + $(INCDIR)/util_script.h diff --git a/web/args.c b/web/args.c new file mode 100755 index 00000000..02e0fad0 --- /dev/null +++ b/web/args.c @@ -0,0 +1,228 @@ +/* 使用方法: 自己先用 r->method_number 判斷是 M_GET 或 M_POST + */ +#include "mod_ptt.h" + +unsigned char xtoc(char ch1, char ch2) { + unsigned char d, up1, up2; + + if (!isxdigit(ch1) || !isxdigit(ch2)) return ' '; + + up1 = toupper(ch1); + up2 = toupper(ch2); + + if (up1>='0' && up1<='9') d = up1-'0'; + else d = up1-'A'+10; + d <<= 4; + if (up2>='0' && up2<='9') d += up2-'0'; + else d += up2-'A'+10; + + return d; +} + +char * cstoxs(pool *p, char *str) +{ + char * newstr = pstrdup(p,""), *po = str; + + for(po = str; *po; po++) + { + if(isprint(*po) && *po!=' ') newstr=psprintf(p, "%s%c", newstr,*po); + else newstr=psprintf(p, "%s%%%X", newstr, *po& 0xFF); + } + return newstr; +} + +int // Ptt: 我重寫拿掉mygetchar 並加上fileupload的功能 +inital_postdata(request_rec *r, int *fileupload, char *boundary, + char **data) +{ + char *buf, *mb; + int size, off = 0, len_read; + void (*handler)(); + + buf = table_get(r->subprocess_env,"CONTENT_TYPE"); + if(!buf || + (strncasecmp(buf,"application/x-www-form-urlencoded",33) && + strncasecmp(buf,"multipart/form-data",19))) + return -1; + + if(!strncasecmp(buf,"multipart/form-data",19)) { + if(!fileupload) return -1; + *fileupload=1; + mb = strchr(buf,'='); + if(mb) { + strcpy(boundary,mb+1); + strtok(boundary, " ;\n"); + } + else return -1; + } + + buf = table_get(r->subprocess_env,"CONTENT_LENGTH"); + if(buf==NULL) return -1; + + size = atoi(buf); + mb = (char *)palloc(r->pool,(size+1)*sizeof(char)); + + if(!mb || + (setup_client_block(r ,REQUEST_CHUNKED_ERROR) != 0) || + (should_client_block(r) == 0)) + return -1; + + hard_timeout("args.c copy script args", r); + handler = signal(SIGPIPE, SIG_IGN); + + while(size-off > 0 && (len_read = get_client_block + (r, mb + off, size - off)) > 0) { + off += len_read; + } + + signal(SIGPIPE, handler); + kill_timeout(r); + + if(len_read < 0) return -1; // 讀的中途有中斷 + mb[size]=0; // Ptt:截掉不需要吧 因為不是用字串處理方式 + (*data) = mb; + return size; +} + +#define ENCODED_NAME " name=\"" +#define ENCODED_FILENAME " filename=\"" +#define ENCODED_CONTENT "Content-Type: " + +//#define FILEDATAFILE DATABASEDIR "/" FDATA + +int +unescape(request_rec *r, char** name, char** value) { + static char *sp=NULL, boundary[150]; + static int fileupload, boundarylen, dsize; + pool *p = r->pool; + char ch, ch1, *dp, *p0, *p1, *temp_sp, *ftype; + int type; + + if (sp==NULL) { + fileupload=0; + switch (r->method_number) { + case M_GET: + if (r->args) sp = pstrdup(p, r->args); + else {sp=NULL; return -1;} + break; + case M_POST: + if ((dsize = + inital_postdata(r, &fileupload, boundary,&sp))<0) + {sp=NULL; return -1; } + if(fileupload) boundarylen = strlen(boundary); + break; + default: + sp=NULL; + return -1; + } + } + + if(fileupload) + { + if(dsize >0 && (temp_sp = memstr(sp, boundary, dsize))) + { + temp_sp += boundarylen; + p0 = strstr(temp_sp, "\r\n\r\n"); + p1 = strstr(temp_sp, "\n\n"); + + if(!((*name) = strstr(temp_sp, ENCODED_NAME))) + {sp=NULL; return -1; } + (*name) += strlen(ENCODED_NAME); + strtok((*name) + 1 , "\""); + if( (!p0 && p1) || (p0 && p1 && p1<p0)) + { + (*value) = sp = p1 + 2; + type = 2; + } + else if(p0) + { + (*value) = sp = p0 + 4; + type = 4; + } + else + { + sp=NULL; + return -1; + } + + if((p1 = memstr(temp_sp, boundary, dsize - boundarylen))) + temp_sp = p1; + else + temp_sp = sp + dsize; + + *(temp_sp - type) = 0; + + // 檢查是不是file 若是就給fileinfo + if((dp=memstr( + (*name) + strlen(*name) +1, ENCODED_FILENAME, dsize)) && + dp < *value) + { + dp += strlen(ENCODED_FILENAME); + p0 = strchr(dp,'"'); + *p0 = 0; + if(p0 - dp>3) + { + fileheader_t *file=(fileheader_t *)pcalloc(p, sizeof(fileheader_t)); + if((ftype = strstr(p0 + 1, ENCODED_CONTENT))) + { + ftype += strlen(ENCODED_CONTENT); + strtok(ftype, "\r\n"); + } + while(p0 > dp && *p0 !='/' && *p0 !='\\') p0--; + strcpy(file->name, p0+1); + strcpy(file->content_type, ftype); + file->icontent_type = filetype(ftype); + // if(file->icontent_type & (FILE_TXT | FILE_HTML)) + // file->size = strlen(sp); + // else + file->size = temp_sp - sp - type; + file->uploadtime = time(NULL); + file->data = (*value); + (*value) = (char *)file; + } + else + { + (*value) = NULL; + } + } + + dsize -= (temp_sp - sp); + sp = temp_sp; + return 1; + } + else + { + sp=NULL; + return -1; + } + } + + dp = (*name) = sp; + while(1) { + ch = *sp++; + switch(ch) { + case '+': + *dp++ = ' '; + break; + case '=': + *dp++ = '\0'; + (*value) = dp; + break; + case '&': case '|': + *dp++ = '\0'; + return 1; + case '\0': case EOF: + *dp = '\0'; + sp=NULL; + return 0; + case '%': + ch = *sp++; ch1 = *sp++; + *dp++ = xtoc(ch, ch1); + break; + default: + *dp++=ch; + break; + } + } +} + diff --git a/web/board.c b/web/board.c new file mode 100644 index 00000000..43347912 --- /dev/null +++ b/web/board.c @@ -0,0 +1,39 @@ +#include "mod_ptt.h" + +extern int numboards; +extern boardheader_t *bcache; +extern int ptt_handler(request_rec *r, void *args); + +int bbs_board(request_rec *r, void *args) +{ + int i; + r->content_type = "text/xml"; + ap_send_http_header(r); + ap_rputs("<hr> Ptt \n", r); +return ptt_handler (r,args); + + ap_rprintf(r,"r->filename : %s <br>",r->filename); + ap_rprintf(r,"r->request_time : %s <br>",ctime(&r->request_time)); + ap_rprintf(r,"r->method : %s <br>",r->method); + ap_rprintf(r,"r->method_number : %d <br>",r->method_number); + ap_rprintf(r,"r->path_info : %s <br>",r->path_info); + ap_rprintf(r,"r->args : %s <br>",r->args); + ap_rprintf(r,"r->unparsed_uri : %s <br>",r->unparsed_uri); + ap_rprintf(r,"r->uri : %s <br>",r->uri); + ap_rprintf(r,"r->handler : %s <br>",r->handler); + ap_rprintf(r,"r->content_type : %s <br>",r->content_type); + ap_rprintf(r, "Server built: \"%s\"\n", ap_get_server_built()); + + ap_rputs("<hr> Ptt \n", r); + + ap_rputs("<XML>",r); +/* + for(i = 0; i++ < numboards; i++) + { + ap_rputs("<board>",r); + ap_rputs("</board>",r); + } +*/ + + return OK; +} diff --git a/web/chmod b/web/chmod new file mode 100644 index 00000000..a91df6d5 --- /dev/null +++ b/web/chmod @@ -0,0 +1 @@ +ftasfdsf @@ -0,0 +1 @@ +lynx -dump ptt.cc/menu diff --git a/web/mail.c b/web/mail.c new file mode 100644 index 00000000..9f226afe --- /dev/null +++ b/web/mail.c @@ -0,0 +1,6 @@ +#include "mod_ptt.h" + +int bbs_mail(request_rec *r, void *args) +{ + return OK; +} diff --git a/web/mod_ptt.c b/web/mod_ptt.c new file mode 100644 index 00000000..3c4309ed --- /dev/null +++ b/web/mod_ptt.c @@ -0,0 +1,284 @@ +#include "mod_ptt.h" +extern SHM_t *SHM; +extern int *GLOBALVAR; + +extern int numboards; +extern boardheader_t *bcache; +typedef struct excfg { + int cmode; /* Environment to which record applies (directory, + * server, or combination). + */ +#define CONFIG_MODE_SERVER 1 +#define CONFIG_MODE_DIRECTORY 2 +#define CONFIG_MODE_COMBO 3 /* Shouldn't ever happen. */ + int local; /* Boolean: "Example" directive declared here? */ + int congenital; /* Boolean: did we inherit an "Example"? */ + char *trace; /* Pointer to trace string. */ + char *loc; /* Location to which this record applies. */ +} excfg; + +static const char *trace = NULL; +static table *static_calls_made = NULL; + +static pool *ptt_pool = NULL; +static pool *ptt_subpool = NULL; + + +module MODULE_VAR_EXPORT ptt_module; +excfg * our_dconfig(request_rec *r) +{ + + return (excfg *) ap_get_module_config(r->per_dir_config, &ptt_module); +} + +static void setup_module_cells() +{ + if (ptt_pool == NULL) { + ptt_pool = ap_make_sub_pool(NULL); + }; + if (static_calls_made == NULL) { + static_calls_made = ap_make_table(ptt_pool, 16); + }; +} + + +static int xml_header(request_rec *r) +{ + r->content_type = "text/xml"; + ap_send_http_header(r); + ap_rputs("<?xml version=\"1.0\" encoding=\"Big5\"?> \n", r); + ap_rprintf(r, "<!-- HTTP-Server-version=\"%s\"\n", + ap_get_server_version()); + ap_rprintf(r," r-filename=\"%s\"\n",r->filename); + ap_rprintf(r," r-request_time=\"%s\"\n",ctime(&r->request_time)); + ap_rprintf(r," r-method=\"%s\"\n",r->method); + ap_rprintf(r," r-method_number=\"%d\"\n",r->method_number); + ap_rprintf(r," r-path_info=\"%s\"\n",r->path_info); + ap_rprintf(r," r-args=\"%s\"\n",r->args); + ap_rprintf(r," r-unparsed_uri=\"%s\"\n",r->unparsed_uri); + ap_rprintf(r," r-handler=\"%s\"\n",r->handler); + ap_rprintf(r," r-content_type=\"%s\"\n",r->content_type); + ap_rprintf(r, " Serverbuilt=\"%s\" \n", ap_get_server_built()); + ap_rprintf(r, " numboards=\"%d\" \n", numboards); + ap_rprintf(r, " shm=\"%d\" \n", SHM->loaded ); + ap_rprintf(r, " max_user=\"%d\" -->", SHM->max_user ); +} +static int userlist(request_rec *r) +{ + int i,offset=0; + userinfo_t *ptr; + xml_header(r); + if (r->header_only) { + return OK; + } + if(r->args) offset=atoi(r->args); + if(offset<0 || offset>SHM->UTMPnumber)offset=0; + + ap_rprintf(r,"<userlist>"); + for(i=offset;i<SHM->UTMPnumber && i<50+offset;i++) + { + ptr= (userinfo_t *)SHM->sorted[SHM->currsorted][0][i]; + if(!ptr || ptr->userid[0]==0 || ptr->invisible ) continue; + ap_rprintf(r,"<user>\n"); + ap_rprintf(r," <id>%d</id>\n",i+1); + ap_rprintf(r," <total>%d</total>\n",SHM->UTMPnumber); + ap_rprintf(r," <uid>%d</uid>\n",ptr->uid); + ap_rprintf(r," <userid>%s</userid>\n",ptr->userid); + ap_rprintf(r," <username>%s</username>\n", + ap_escape_html(r->pool,ptr->username)); + ap_rprintf(r," <from>%s</from>\n",ptr->from); + ap_rprintf(r," <from_alias>%d</from_alias>\n",ptr->from_alias); + ap_rprintf(r," <mailalert>%d</mailalert>\n",ptr->mailalert); + ap_rprintf(r," <mind>%s</mind>\n",ap_escape_html(r->pool,ptr->mind)); + ap_rprintf(r,"</user>"); + } + ap_rprintf(r,"</userlist>"); +} +static int showboard(request_rec *r, int id) +{ + int i; + boardheader_t *bptr=NULL; + id=id-1; + ap_rprintf(r,"<brdlist>"); + bptr = (boardheader_t *)bcache[id].firstchild[0]; + for(; bptr!= (boardheader_t*)~0; ) + { + if((bcache[id].brdattr&BRD_HIDE)|| + bcache[id].level&& !(bcache[id].brdattr & BRD_POSTMASK )) continue; + ap_rprintf(r,"<brd>\n"); + i=(bptr-bcache); + ap_rprintf(r," <bid>%d</bid>",i+1); + ap_rprintf(r," <brdname>%s</brdname>\n",bptr->brdname); + ap_rprintf(r," <title>%s</title>\n",ap_escape_html(r->pool,bptr->title)); + ap_rprintf(r," <nuser>%d</nuser>\n",bptr->nuser); + ap_rprintf(r," <gid>%d</gid>\n",bptr->gid); + ap_rprintf(r," <childcount>%d</childcount>\n",bptr->childcount); + ap_rprintf(r," <BM>%s</BM>\n",bptr->BM); + ap_rprintf(r," <brdattr>%d</brdattr>\n",bptr->brdattr); + ap_rprintf(r," <total>%d</total>\n",SHM->total[i]); + ap_rprintf(r,"</brd>\n"); + bptr=(boardheader_t*)bptr->next[0]; + } + + ap_rprintf(r,"</brdlist>"); +} + + +static int showpost(request_rec *r,int bid,int id, int num) +{ + int i; + num=256; + id=1; + char path[512]; + fileheader_t headers[256]; + memset(headers,0, sizeof(fileheader_t)*256); + sprintf(path,BBSHOME"/boards/%c/%s/.DIR", + bcache[bid-1].brdname[0],bcache[bid-1].brdname); + get_records(path, headers, sizeof(fileheader_t)*256, id,num); + + ap_rprintf(r,"<postlist>"); + + for(i=0;i<256;i++) + { + ap_rprintf(r,"<post>\n"); + ap_rprintf(r," <id>%d</id>",i+1); + ap_rprintf(r," <filename>%s</filename>\n",headers[i].filename); + ap_rprintf(r," <owner>%s</owner>\n",headers[i].owner); + ap_rprintf(r," <date>%s</date>\n",headers[i].date); + ap_rprintf(r," <title>%s</title>\n", + ap_escape_html(r->pool,headers[i].title)); + ap_rprintf(r," <money>%d</money>\n",headers[i].money); + ap_rprintf(r," <filemode>%c</filemode>\n",headers[i].filemode); + ap_rprintf(r," <recommend>%d</recommend>\n",headers[i].recommend); + ap_rprintf(r,"</post>\n"); + } + ap_rprintf(r,"</postlist>"); +} +static int showmenujs(request_rec *r) +{ + int i; + boardheader_t *bptr; + r->content_type = "text/text"; + ap_send_http_header(r); + ap_rputs("d=new dTree('d');\n",r); + ap_rputs("d.add(0,-1,'Class','');\n",r); + for(i=1;i<=numboards;i++) + { + bptr=&bcache[i-1]; + if(!isalpha(bptr->brdname[0]))continue; + + ap_rprintf(r,"d.add(%d,%d,\"%s %s..\",'/boards?%s');\n", + i,bptr->gid-1, + bptr->gid==1?"":bptr->brdname, + ap_escape_quotes(r->pool, + ap_escape_html(r->pool,bptr->title+7)),i); + } + ap_rputs("d.draw()\n",r); + return OK; +} + +static int showxml(request_rec *r) +{ + int bid=1; + xml_header(r); + if (r->header_only) { + return OK; + } + if(r->args) bid=atoi(r->args); + if(bid<1 || bid>numboards)bid=1; + + if( + !(bcache[bid-1].brdattr&BRD_HIDE)&& + !(bcache[bid-1].level&&!(bcache[bid-1].brdattr & BRD_POSTMASK))) + if( bid==1||bcache[bid-1].brdattr&BRD_GROUPBOARD) + showboard(r,bid); + else + showpost(r,bid,0,0); + return OK; +} +static int ptt_handler(request_rec *r) +{ + excfg *dcfg; + + dcfg = our_dconfig(r); + + ap_soft_timeout("send ptt call trace", r); + + if(!strncmp(r->unparsed_uri,"/menu",5)) + showmenujs(r); + else if(!strncmp(r->unparsed_uri,"/userlist",9)) + userlist(r); + else + showxml(r); + + ap_kill_timeout(r); + return OK; +} + +/* OK Handler accepted the request and did its thing with it. */ +/* DECLINED Handler took no action. */ +/* HTTP_mumble Handler looked at request and found it wanting. */ + +static void ptt_child_init(server_rec *s, pool *p) +{ + + char *note; + char *sname = s->server_hostname; + attach_SHM(); + + + setup_module_cells(); + sname = (sname != NULL) ? sname : ""; + note = ap_pstrcat(p, "ptt_child_init(", sname, ")", NULL); +} + +static void ptt_child_exit(server_rec *s, pool *p) +{ + + char *note; + char *sname = s->server_hostname; + + /* + * The arbitrary text we add to our trace entry indicates for which server + * we're being called. + */ + sname = (sname != NULL) ? sname : ""; + note = ap_pstrcat(p, "ptt_child_exit(", sname, ")", NULL); +} + +static const handler_rec ptt_handlers[] = +{ + {"ptt_h", ptt_handler}, + {NULL} +}; + +module MODULE_VAR_EXPORT ptt_module = +{ + STANDARD_MODULE_STUFF, + NULL, /* module initializer */ + NULL, /* per-directory config creator */ + NULL, /* dir config merger */ + NULL, /* server config creator */ + NULL, /* server config merger */ + NULL, /* command table */ + ptt_handlers, /* [9] list of handlers */ + NULL, /* [2] filename-to-URI translation */ + NULL, /* [5] check/validate user_id */ + NULL, /* [6] check user_id is valid *here* */ + NULL, /* [4] check access by host address */ + NULL, /* [7] MIME type checker/setter */ + NULL, /* [8] fixups */ + NULL, /* [10] logger */ +#if MODULE_MAGIC_NUMBER >= 19970103 + NULL, /* [3] header parser */ +#endif +#if MODULE_MAGIC_NUMBER >= 19970719 + ptt_child_init, /* process initializer */ +#endif +#if MODULE_MAGIC_NUMBER >= 19970728 + ptt_child_exit, /* process exit/cleanup */ +#endif +#if MODULE_MAGIC_NUMBER >= 19970902 + NULL +#endif +}; diff --git a/web/mod_ptt.h b/web/mod_ptt.h new file mode 100644 index 00000000..125046d6 --- /dev/null +++ b/web/mod_ptt.h @@ -0,0 +1,13 @@ +#include "httpd.h" +#include "http_config.h" +#include "http_core.h" +#include "http_log.h" +#include "http_main.h" +#include "http_protocol.h" +#include "util_script.h" +#include "bbs.h" + +#include <stdio.h> + + +#define PATHLEN 512 diff --git a/web/mytime.h b/web/mytime.h new file mode 100755 index 00000000..c9e4f29d --- /dev/null +++ b/web/mytime.h @@ -0,0 +1,189 @@ +/* Ptt : 常用函式整理 */ + +/* + * 時間處理 + */ +#include <time.h> +#ifdef _BBS_UTIL + #undef pstrdup + #define pstrdup(p, str) strdup(str) +#endif + +int +mygetdate(time_t clock, int *year, int *mon, int *mday, int *week) +{ + struct tm *mytm = localtime(&clock); + if(year) *year = mytm->tm_year; /* 98 */ + if(mon) *mon = mytm->tm_mon + 1; /* 1~12 */ + if(mday) *mday = mytm->tm_mday; /* 1~31 */ + if(week) *week = mytm->tm_wday; /* 0~6 */ + return 0; +} + +char * +Cdatenum_slash(pool *p,time_t *clock) /* 98/04/21 */ +{ + char foo[22]; + struct tm *mytm = localtime(clock); + strftime(foo, 22, "%y/%m/%d", mytm); + return pstrdup(p, foo); +} + +char * +Cdatenum(pool *p,time_t *clock) /* 980421 */ +{ + char foo[22]; + struct tm *mytm = localtime(clock); + strftime(foo, 22, "%y%m%d", mytm); + return pstrdup(p, foo); +} + + +#ifndef _BBS_UTIL +char * +Cdatefullnum(pool *p,time_t *clock) /* 19980421 */ +{ + char foo[22]; + struct tm *mytm = localtime(clock); + strftime(foo, 22, "%Y%m%d", mytm); + return pstrdup(p, foo); +} +#else +char * +Cdatefullnum(char *p,time_t *clock) /* 19980421 */ +{ + static char foo[22]; + struct tm *mytm = localtime(clock); + strftime(foo, 22, "%Y%m%d", mytm); + return foo; +} +#endif + +char * +Cdate(char *p,time_t *clock) +{ + char foo[22]; + struct tm *mytm = localtime(clock); + strftime(foo, 22, "%D %T %a", mytm); + return pstrdup(p, foo); +} + +char * +Cdatelite(char *p,time_t *clock) +{ + char foo[18]; + struct tm *mytm = localtime(clock); + strftime(foo, 18, "%D %T", mytm); + return pstrdup(p, foo); +} + +char * +whattime(char *p,time_t *clock) +{ + char foo[18]; + struct tm *mytm = localtime(clock); + strftime(foo, 18, "%H:%M:%S", mytm); + return pstrdup(p, foo); +} + +char * +whatyear(char *p,time_t *clock) +{ + char foo[6]; + struct tm *mytm = localtime(clock); + strftime(foo, 6, "%Y", mytm); + return pstrdup(p, foo); +} + +char * +whatmonth(char *p,time_t *clock) +{ + char foo[4]; + struct tm *mytm = localtime(clock); + strftime(foo, 4, "%m", mytm); + return pstrdup(p, foo); +} + +char * +whatday(char *p,time_t *clock) +{ + char foo[4]; + struct tm *mytm = localtime(clock); + strftime(foo, 4, "%d", mytm); + return pstrdup(p, foo); +} + +char * +C_week(pool *p, int a) +{ + char foo[5]=""; + switch(a) + { + case 0: + case 7: + strcpy(foo,"日"); + break; + case 1: + strcpy(foo,"一"); + break; + case 2: + strcpy(foo,"二"); + break; + case 3: + strcpy(foo,"三"); + break; + case 4: + strcpy(foo,"四"); + break; + case 5: + strcpy(foo,"五"); + break; + case 6: + strcpy(foo,"六"); + break; + } + return pstrdup(p, foo); +} + +char * +whatweek(char *p,time_t *clock) +{ + struct tm *mytm = localtime(clock); + return C_week(p, mytm->tm_wday); +} + +char * +whathour(char *p,time_t *clock) +{ + char foo[4]=""; + struct tm *mytm = localtime(clock); + strftime(foo, 6, "%H", mytm); + return pstrdup(p, foo); +} + +char * +whatminute(char *p,time_t *clock) +{ + char foo[4]=""; + struct tm *mytm = localtime(clock); + strftime(foo, 6, "%M", mytm); + return pstrdup(p, foo); +} + +char * +whatsecond(char *p,time_t *clock) +{ + char foo[4]=""; + struct tm *mytm = localtime(clock); + strftime(foo, 6, "%S", mytm); + return pstrdup(p, foo); +} + +char * +Wholetime(char *p,time_t *clock) /* 19980421 */ +{ + char foo[40]; + struct tm *mytm = localtime(clock); + strftime(foo, 40, "%Y年%m月%d日%H時%M分%S秒", mytm); + return pstrdup(p, foo); +} diff --git a/web/parse_html.c b/web/parse_html.c new file mode 100755 index 00000000..402412de --- /dev/null +++ b/web/parse_html.c @@ -0,0 +1,294 @@ +#include "mod_ptt.h" +#include <time.h> +#include <math.h> +#define KUSERINFO "$userinfo$" +#define KUSERID "$userid$" +#define KUSERNAME "$username$" +#define KUSERMONEY "$usermoney$" +#define KTIMEYEAR "$timeyear$" +#define KTIMEMONTH "$timemonth$" +#define KTIMEMDAY "$timemday$" +#define KTIMEWEEK "$timeweek$" +#define KSERVERTIME "$servertime$" +#define KTIMEHOUR "$hour$" +#define KTIMEMINUTE "$minute$" +#define KTIMESECOND "$second$" +#define KMSGONLOAD "$MSGonLoad$" +#define KFCSONLOAD "$FCSonLoad$" +#define KHTMLTITLE "$HTMLtitle$" +#define KSCROLLTITLE "$SCROLLtitle$" +#define KBGCOLOR "$BGCOLOR$" +#define KBGSOUND "$BGSOUND$" +#define KINCHTML "$file:" + + + +char * +ap_parseline(request_rec *r, const char *str, char *str_substiute[]) { + int i, off=0; + char *strbuf, *po; + pool *p = r->pool; + strbuf = pstrdup(p, str); + + if(str_substiute == NULL) return strbuf; + for(i=0; str_substiute[i]!=NULL; i+=2) + { + off = 0; + while(po = strstr(strbuf + off, str_substiute[i])) + { + *po = 0; + strbuf = pstrcat(p, strbuf, str_substiute[i+1] !=NULL + ? str_substiute[i+1] : "", po+strlen(str_substiute[i]), NULL); + off += str_substiute[i+1] ? strlen(str_substiute[i+1]) : 0; + } + } + return strbuf; +} + +char * +ap_standard_parseline(request_rec *r, char *str) +{ + time_t now = time(NULL); + pool *p = r->pool; + char *str_substiute[]= // 關鍵字的代換表 + { + KUSERID, "ptt", + KUSERNAME, "name", +/* + KTIMEYEAR, whatyear(p,&now), + KTIMEMONTH,whatmonth(p,&now), + KTIMEMDAY, whatday(p,&now), + KTIMEWEEK, whatweek(p,&now), + KSERVERTIME, whattime(p,&now), + KTIMEHOUR, whathour(p,&now), + KTIMEMINUTE, whatminute(p,&now), + KTIMESECOND, whatsecond(p,&now), +*/ + KUSERINFO, NULL, + KUSERMONEY, "100", + NULL,NULL + }; + return ap_parseline(r, str, str_substiute); +} + +int +ap_showfile(request_rec *r, char *filename, char *table[], char *t2[], FILE *fo) +{ + pool *p = r->pool; + FILE *fp = pfopen(p, filename, "r"); + char *str, *incfile, buf[512]; + + if (!fp) { +#if DEBUG + rputs(filename, r); +#endif + return -1; + } + + while (fgets(buf, 512, fp)) + { + + str = ap_standard_parseline(r, + ap_parseline(r, + ap_parseline(r, buf, table), + t2)); + + if ((incfile = strstr(str, KINCHTML)) != NULL) { + incfile += strlen(KINCHTML); + incfile = strtok(incfile, "$"); +#if 0 + if (*incfile != '/') + incfile = ap_pstrcat(p, TEMPLATEDIR "/", incfile, NULL); +#endif + ap_showfile(r, incfile, table, t2, fo); + } else if(fo) fputs(str, fo); + else rputs(str, r); + } + + pfclose(p, fp); + return 0; +} + +char * +add_href(pool *p, char *l) +{ + char *href[] = {"http://", "ftp://", "gopher://", "file://", + "telnet://", "mailto:", NULL}, + *end, url[PATHLEN], *tl, *po; + int i, urllen, off; + + tl = pstrdup(p, l); + + for(i=0; href[i]!=NULL; i++) + { + off = 0; + //Ptt: while 應該用 while 但 while 有bug + if((po = strstr(tl + off, href[i]))) + { + for(end = po; (*end>='&' && *end<='z')||*end=='~' ; end++); + urllen = end - po; + + if(urllen > PATHLEN) + { + off += PATHLEN; continue; + } + + strncpy(url, po, urllen); + *po= 0; + url[urllen] = 0; + tl = psprintf(p, "%s<a href=\"%s\" target=\"%s\">%s</a>%s", tl, + url, "new", url, end); + off += 2 * urllen + 15; + } + } + + return tl; +} + +/* + format: + char *name, void *ptr, size_t length + char *name, int *ptr, -1 + char *name, char **ptr, 0 +*/ +int +GetQueryDatas(request_rec *r, int **table) +{ + int rc, i, match=0, dlen, maxlen; + char *name, *value, *str; + pool *p = r->pool; + + for(i=1; table[i]!=NULL; i+=3) + { + if((int) table[i+1]) *table[i]=0; + else (char *) (*table[i]) = pstrdup(p, ""); + } + do + { + if((rc = unescape(r, &name, &value))<0) break; + for(i=0; table[i]; i+=3) + { + if(!strcmp((char *)table[i], name)) break; + +#if 0 +/* SiE990313 test: 抓 未定義的變數 */ + if(!strcmp((char *)table[i], "$SPARE$")) + { + (char *) (*table[i + 1]) = pstrdup(p, name); + continue; + } +#endif + } + if(table[i] && table[i+1]) + { + if((maxlen = (int) table[i+2]) > 0) + { + if(!*value) continue; + dlen = strlen((char *)table[i+1]); + str = ap_escape_html(p, value); + if(maxlen > dlen) + strexam( + strncat((char *)table[i+1],str,maxlen-dlen) + ); + } + else if((int) table[i+2] == 0) // for file upload + { +// str = ap_escape_html(p, value); + //if(value) + (*table[i+1]) = (int) value; +// else (*table[i+1]) = (int) pstrdup(p,""); + } + else + { + if(!*value) continue; + *(table[i+1]) += atoi(value); + } + match++; + } + } while(rc>0); + return match; +} + + +int +ap_url_redirect(request_rec *r, char *url) +{ + r->status = REDIRECT; + + ap_table_setn(r->headers_out, "Location", pstrdup(r->pool, url)); + return MOVED; + //return REDIRECT, MOVED 或 HTTP_SEE_OTHER 都可 +} + +char * +pint2str(pool* p, int c) +{ + return ap_psprintf(p,"%d",c); +} + +char* +preplace(request_rec *r, char* src, char* sig, char* rep) +{ + char *ptr; + int siglen=strlen(sig), off=0; + + while((ptr = strstr(src+off,sig))) + { + *ptr = 0; + src = pstrcat(r->pool, src, rep, NULL); + off = strlen(src); + src = pstrcat(r->pool, src, ptr+siglen, NULL); + } + return src; +} + +int +hex2dig(char *str) +{ + int base,ret=0,i,len=strlen(str); + + for(i=0; i<len; i++) + { + if(str[i]>='a' && str[i]<='f') base = str[i]-'a'+10; + else if(str[i]>='A' && str[i]<='F') base = str[i]-'A'+10; + else if(str[i]>='0' && str[i]<='9') base = str[i]-'0'; + else return -1; + + ret += base*pow(16,len-i-1); + } + return ret; +} + +char * +pstrncpy(pool* p, char tmp[], int n) +{ + char *ptr; + ptr=pstrdup(p,tmp); + *(ptr+n)=0; + return psprintf(p,"%s",ptr); +} + +char * +GetPathToken(request_rec *r, int count) +{ + char *str, *token, *sepr = "/\\?&"; + int i; + str = pstrdup(r->pool, r->path_info + 1); + token = strtok(str, sepr); + for( i = 1 ; i < count; i++) + { + token = strtok(NULL, sepr); + if(!token) return "-1"; /* Heat:count超過也要考慮 */ + } + return token; +} + + +/* + 個人信件夾檔保管方式: + + mail/@/rec/FF/F/UUDDTT + mail/@/dat/FF/F/UUDDTT + +*/ + diff --git a/web/post.c b/web/post.c new file mode 100644 index 00000000..3e67937e --- /dev/null +++ b/web/post.c @@ -0,0 +1,6 @@ +#include "mod_ptt.h" + +int bbs_post(request_rec *r, void *args) +{ + return OK; +} @@ -0,0 +1 @@ +sudo apachectl restart @@ -0,0 +1 @@ +sudo apachectl stop diff --git a/web/stuff.c b/web/stuff.c new file mode 100755 index 00000000..b02dbb0d --- /dev/null +++ b/web/stuff.c @@ -0,0 +1,269 @@ +/* Ptt : 常用字串函式整理 */ +#include "mod_ptt.h" + +// 缺少 escape_url的東西 + +/* + * 檔案判別 + */ + + /* 傳回:路徑大小 */ + +off_t +dashs(fname) + char *fname; +{ + struct stat st; + + if (!stat(fname, &st)) + return (st.st_size); + else + return 0; /* 無此檔是 size 0 */ +} + + /* 傳回:路徑時間 */ +long +dasht(char *fname) +{ + struct stat st; + + if (!stat(fname, &st)) + return (st.st_mtime); + else + return -1; +} + + /* 傳回:路徑是否為link檔 */ +int +dashl(char *fname) +{ + struct stat st; + return (lstat(fname, &st) == 0 && S_ISLNK(st.st_mode)); +} + + /* 傳回:路徑是否為檔案 */ +dashf(char *fname) +{ + struct stat st; + + return (stat(fname, &st) == 0 && S_ISREG(st.st_mode)); +} + +/* 字串的小寫 */ +#define char_lower(c) ((c >= 'A' && c <= 'Z') ? c|32 : c) + +void +str_lower(t, s) + char *t, *s; +{ + register char ch; + do + { + ch = *s++; + *t++ = char_lower(ch); + } while (ch); +} + +int +str_ncmp(s1, s2, n) + char *s1, *s2; + int n; +{ + int c1, c2; + + while (n--) + { + c1 = *s1++; + if (c1 >= 'A' && c1 <= 'Z') + c1 |= 32; + + c2 = *s2++; + if (c2 >= 'A' && c2 <= 'Z') + c2 |= 32; + + if (c1 -= c2) + return (c1); + + if (!c2) + break; + } + return 0; +} +char * +memstr(char *mem, char *str, int size) +{ + char *loc, *ptr=mem, *end=mem+size; + int len = strlen(str); + while((loc = memchr(ptr, *str, size))) + { + if(!strncmp(loc, str, len)) + return loc; + ptr = loc +1; + size = (end - ptr); + if(size <=0 ) return NULL; + } + return NULL; +} + +/* 傳回: strstr的比較但不計大小寫的結果 */ +/* +char * +strcasestr(str, tag) + char *str, *tag; +{ + char buf[BUFLEN]; + + str_lower(buf, str); + return strstr(buf, tag); +} +*/ + +/* 傳回: 一個checksum 給字串比較用 */ + +int str_checksum(char *str) +{ + int n=1; + if(strlen(str) < 6) return 0; + while(*str) + n += *str++ ^ n; + return n; +} + +int +not_alpha(ch) + register char ch; +{ + return (ch < 'A' || (ch > 'Z' && ch < 'a') || ch > 'z'); +} + +int +not_alnum(ch) + register char ch; +{ + return (ch < '0' || (ch > '9' && ch < 'A') || + (ch > 'Z' && ch < 'a') || ch > 'z'); +} + +char +ch2ph(char ch) +{ + static const + // a b c d e f g h i j k l m n o + char table[]={'2','2','2','3','3','3','4','4','4','5','5','5','6','6','6', + // p q r s t u v w x y z + '7','1','7','7','8','8','8','9','9','9','1'}; + static char d; + d = char_lower(ch); + if(d>='a' && d<='z') d=table[d-'a']; + return d; +} + +void +archiv32(chrono, fname) + time_t chrono; /* 32 bits */ + char *fname; /* 7 chars */ +{ + char *str; + char radix32[32] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', + 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', + 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', + }; + + str = fname + 7; + *str = '\0'; + for (;;) + { + *(--str) = radix32[chrono & 31]; + if (str == fname) + return; + chrono >>= 5; + } +} + +/* ARPANET時間格式 */ +char * +Atime(clock) + time_t *clock; +{ + static char datemsg[40]; + /* ARPANET format: Thu, 11 Feb 1999 06:00:37 +0800 (CST) */ + /* strftime(datemsg, 40, "%a, %d %b %Y %T %Z", localtime(clock)); */ + /* time zone的傳回值不知和ARPANET格式是否一樣,先硬給,同sendmail*/ + strftime(datemsg, 40, "%a, %d %b %Y %T +0800 (CST)", localtime(clock)); + return (datemsg); +} + + +/* userid是否合法 */ +int +bad_user_id(userid) + char *userid; +{ + register char ch; + if (strlen(userid) < 2) + return 1; + if (not_alpha(*userid)) + return 1; + if (!strcasecmp(userid, "new") || !strcasecmp(userid, "guest") || + !strcasecmp(userid, "root") || !strcasecmp(userid, "webadm") || + !strncasecmp(userid,"yam",3) + ) + return 1; + + while (ch = *(++userid)) + { + if (not_alnum(ch) || ch == '0') + return 1; + } + return 0; +} + + +int +logfile(pool *p, char *filename,char *buf) +{ + FILE *fp; + time_t now; + if( (fp = ap_pfopen(p, filename, "a" )) ) { + + fputs( buf, fp ); + if(!strchr(buf,'\n')) + { + now = time(NULL); + fputs(ctime(&now), fp); + } + ap_pfclose(p, fp ); + return 0; + } + else{ + printf("error open file"); + return -1; + } +} + +/* 檢查中文斷字問題 */ +char *strexam(char *s) +{ + int i; + int odd; + for (i = 0, odd = 0; s[i]; i++) + if (odd) odd = 0; + else if (s[i] & 128) odd = 1; + if (odd) s[--i] = 0; + return s; +} + +int +maxline(char *data,char *newline, int max) +{ + register int n, nlen=strlen(newline); + register char *po; + + for(n=0, po = data; (po = strstr(po, newline)); po+=nlen) + { + if(++n>=max) {*po=0; return -1;} + } + return n; +} @@ -0,0 +1 @@ +tail /var/log/httpd-error.log diff --git a/web/user.c b/web/user.c new file mode 100644 index 00000000..fe5d0696 --- /dev/null +++ b/web/user.c @@ -0,0 +1,6 @@ +#include "mod_ptt.h" + +int bbs_user(request_rec *r, void *args) +{ + return OK; +} |