int find_save_lost(struct boardheader *bhp) { char buf[200]; int i; for (i = 0; i < HASHSIZE; i++) { nfile[i] = 0; } otherfile[0] = 0; sprintf(buf, MY_BBS_HOME "/boards/%s", bhp->filename); if (getallpost(buf) < 0) return -1; sprintf(buf, MY_BBS_HOME "/boards/%s/.DIR", bhp->filename); if (file_isfile(buf)) if (useindexfile(buf) < 0) return -1; sprintf(buf, MY_BBS_HOME "/boards/%s/.DIGEST", bhp->filename); if (file_isfile(buf)) if (useindexfile(buf) < 0) return -1; sprintf(buf, MY_BBS_HOME "/boards/%s/.DELETED", bhp->filename); if (file_isfile(buf)) if (useindexfile(buf) < 0) return -1; sprintf(buf, MY_BBS_HOME "/boards/%s/.JUNK", bhp->filename); if (file_isfile(buf)) if (useindexfile(buf) < 0) return -1; sprintf(buf, MY_BBS_HOME "/boards/%s", bhp->filename); save_lost(buf); return 0; }
int file_rmrf (const char *path) { if (file_isdir (path)) { dirlist_t list; if (file_listdir (path, &list) != 0) return -1; int i; for (i = 0; i < list.length; i++) { if (strcmp (".", list.paths[i]) == 0 || strcmp ("..", list.paths[i]) == 0) continue; char *next = path_join (path, list.paths[i]); int ret = file_rmrf (next); free (next); if (ret != 0) { file_free_dirlist (&list); return ret; } } file_free_dirlist (&list); if (rmdir (path) != 0) return -1; } else if (file_isfile (path) || file_islink (path)) { return unlink (path); } return 0; }
int file_mkdirs (const char *path, int mode) { char dir[1024]; char *p; if (file_isdir (path)) return 0; if (file_isfile (path)) { errno = EEXIST; return -1; } file_dirname (path, dir, sizeof (dir)); if (strcmp (dir, ".") != 0) file_mkdirs (dir, mode); if (mkdir (path, mode) != 0) return -1; return 0; }
int bbsqry_main() { FILE *fp; char userid[14], filename[80], buf[512]; struct userec *x; int tmp2; struct in_addr in; html_header(1); check_msg(); changemode(QUERY); strsncpy(userid, getparm("U"), 13); if (!userid[0]) strsncpy(userid, getparm("userid"), 13); printf("<body><center>"); printf("%s -- 查询网友<hr>\n", BBSNAME); if (userid[0] == 0) { printf("<form name=qry action=bbsqry>\n"); printf ("请输入用户名: <input name=userid maxlength=12 size=12>\n"); printf("<input type=submit value=查询用户>\n"); printf("</form><hr>\n"); printf("<script>document.qry.userid.focus();</script>"); http_quit(); } if (getuser(userid, &x) <= 0) { printf("不可能,肯定是你敲错了,根本没这人啊"); printf("<p><a href=javascript:history.go(-1)>快速返回</a>"); http_quit(); } printf("</center><pre>\n"); if (x->mypic) { printf("<table align=left><tr><td><center>"); printmypic(x->userid); printf("</center></td></tr></table>"); } printf("<b><font size=+1>%s</font></b> (<font class=gre>%s</font>) " "共上站 <font class=gre>%d</font> 次," "发表文章 <font class=gre>%d</font> 篇\n", x->userid, x->username, x->numlogins, x->numposts); // show_special(x->userid); in.s_addr = x->lasthost & 0x0000ffff; printf ("上次在 <font color=green>%s</font> 从 <font color=green>%s</font> 到本站一游。<br>", Ctime(x->lastlogin), inet_ntoa(in)); mails(userid, &tmp2); printf("信箱:[<font color=green>%s</font>],", tmp2 ? "⊙" : " "); if (!strcasecmp(x->userid, currentuser->userid)) { printf ("经验值:[<font color=green>%d</font>](<font color=olive>%s</font>) ", countexp(x), cuserexp(countexp(x))); printf ("表现值:[<font color=green>%d</font>](<font color=olive>%s</font>) ", countperf(x), cperf(countperf(x))); } if (x->dieday) { printf ("<br>已经离开了人世,呜呜...<br>还有 [<b>%d</b>] 天就要转世投胎了<br>", countlife(x)); } else { printf("生命力:[<font color=red>%d</font>]。<br>", countlife(x)); if (x->userlevel & PERM_BOARDS) { int i; printf("担任版务:"); for (i = 0; i < MAXBOARD && i < shm_bcache->number; i++) bm_printboard(&shm_bcache->bcache[i], x->userid); printf("<br>"); } if (!show_onlinestate(userid)) { printf ("目前不在站上, 上次离站时间 [<font color=blue>%s</font>]\n\n", (x->lastlogout >= x->lastlogin) ? Ctime(x-> lastlogout) : "因在线上或不正常断线不详"); } } printf("\n"); printf("</pre><table width=100%%><tr><td>"); sethomefile(filename, x->userid, "plans"); fp = fopen(filename, "r"); sprintf(filename, "00%s-plan", x->userid); fdisplay_attach(NULL, NULL, NULL, NULL); if (fp) { while (1) { if (fgets(buf, 256, fp) == 0) break; if (!strncmp(buf, "begin 644 ", 10)) { errlog("old attach %s", filename); fdisplay_attach(stdout, fp, buf, filename); continue; } fhhprintf(stdout, "%s", buf); } fclose(fp); } else { printf("<font color=teal>没有个人说明档</font><br>"); } printf("</td></tr></table>"); printf ("<br><br><a href=bbspstmail?userid=%s&title=没主题>[书灯絮语]</a> ", x->userid); printf("<a href=bbssendmsg?destid=%s>[发送讯息]</a> ", x->userid); printf("<a href=bbsfadd?userid=%s>[加入好友]</a> ", x->userid); printf("<a href=bbsfdel?userid=%s>[删除好友]</a> ", x->userid); if (x->userlevel & PERM_SPECIAL8) { printf ("<a href=bbs0an?path=/groups/GROUP_0/Personal_Corpus/%c/%s>[个人文集]</a> ", mytoupper(x->userid[0]), x->userid); } sethomefile(filename, x->userid, "B/config"); if (file_isfile(filename)) { printf ("<a href=blog?U=%s>[Blog]</a>", x->userid); } printf("<hr>"); printf("<center><form name=qry action=bbsqry>\n"); printf("请输入用户名: <input name=userid maxlength=12 size=12>\n"); printf("<input type=submit value=查询用户>\n"); printf("</form><hr>\n"); printf("</body>\n"); http_quit(); return 0; }
/* ** Parse the given URL. Populate members of the provided UrlData structure ** as follows: ** ** isFile True if FILE: ** isHttps True if HTTPS: ** isSsh True if SSH: ** protocol "http" or "https" or "file" ** name Hostname for HTTP:, HTTPS:, SSH:. Filename for FILE: ** port TCP port number for HTTP or HTTPS. ** dfltPort Default TCP port number (80 or 443). ** path Path name for HTTP or HTTPS. ** user Userid. ** passwd Password. ** hostname HOST:PORT or just HOST if port is the default. ** canonical The URL in canonical form, omitting the password ** */ void url_parse_local( const char *zUrl, unsigned int urlFlags, UrlData *pUrlData ){ int i, j, c; char *zFile = 0; if( zUrl==0 ){ zUrl = db_get("last-sync-url", 0); if( zUrl==0 ) return; if( pUrlData->passwd==0 ){ pUrlData->passwd = unobscure(db_get("last-sync-pw", 0)); } } if( strncmp(zUrl, "http://", 7)==0 || strncmp(zUrl, "https://", 8)==0 || strncmp(zUrl, "ssh://", 6)==0 ){ int iStart; char *zLogin; char *zExe; char cQuerySep = '?'; pUrlData->isFile = 0; pUrlData->useProxy = 0; if( zUrl[4]=='s' ){ pUrlData->isHttps = 1; pUrlData->protocol = "https"; pUrlData->dfltPort = 443; iStart = 8; }else if( zUrl[0]=='s' ){ pUrlData->isSsh = 1; pUrlData->protocol = "ssh"; pUrlData->dfltPort = 22; pUrlData->fossil = "fossil"; iStart = 6; }else{ pUrlData->isHttps = 0; pUrlData->protocol = "http"; pUrlData->dfltPort = 80; iStart = 7; } for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!='@'; i++){} if( c=='@' ){ /* Parse up the user-id and password */ for(j=iStart; j<i && zUrl[j]!=':'; j++){} pUrlData->user = mprintf("%.*s", j-iStart, &zUrl[iStart]); dehttpize(pUrlData->user); if( j<i ){ if( ( urlFlags & URL_REMEMBER ) && pUrlData->isSsh==0 ){ urlFlags |= URL_ASK_REMEMBER_PW; } pUrlData->passwd = mprintf("%.*s", i-j-1, &zUrl[j+1]); dehttpize(pUrlData->passwd); } if( pUrlData->isSsh ){ urlFlags &= ~URL_ASK_REMEMBER_PW; } zLogin = mprintf("%t@", pUrlData->user); for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){} pUrlData->name = mprintf("%.*s", j-i-1, &zUrl[i+1]); i = j; }else{ int inSquare = 0; int n; for(i=iStart; (c=zUrl[i])!=0 && c!='/' && (inSquare || c!=':'); i++){ if( c=='[' ) inSquare = 1; if( c==']' ) inSquare = 0; } pUrlData->name = mprintf("%.*s", i-iStart, &zUrl[iStart]); n = strlen(pUrlData->name); if( pUrlData->name[0]=='[' && n>2 && pUrlData->name[n-1]==']' ){ pUrlData->name++; pUrlData->name[n-2] = 0; } zLogin = mprintf(""); } url_tolower(pUrlData->name); if( c==':' ){ pUrlData->port = 0; i++; while( (c = zUrl[i])!=0 && fossil_isdigit(c) ){ pUrlData->port = pUrlData->port*10 + c - '0'; i++; } pUrlData->hostname = mprintf("%s:%d", pUrlData->name, pUrlData->port); }else{ pUrlData->port = pUrlData->dfltPort; pUrlData->hostname = pUrlData->name; } dehttpize(pUrlData->name); pUrlData->path = mprintf("%s", &zUrl[i]); for(i=0; pUrlData->path[i] && pUrlData->path[i]!='?'; i++){} if( pUrlData->path[i] ){ pUrlData->path[i] = 0; i++; } zExe = mprintf(""); while( pUrlData->path[i]!=0 ){ char *zName, *zValue; zName = &pUrlData->path[i]; zValue = zName; while( pUrlData->path[i] && pUrlData->path[i]!='=' ){ i++; } if( pUrlData->path[i]=='=' ){ pUrlData->path[i] = 0; i++; zValue = &pUrlData->path[i]; while( pUrlData->path[i] && pUrlData->path[i]!='&' ){ i++; } } if( pUrlData->path[i] ){ pUrlData->path[i] = 0; i++; } if( fossil_strcmp(zName,"fossil")==0 ){ pUrlData->fossil = zValue; dehttpize(pUrlData->fossil); zExe = mprintf("%cfossil=%T", cQuerySep, pUrlData->fossil); cQuerySep = '&'; } } dehttpize(pUrlData->path); if( pUrlData->dfltPort==pUrlData->port ){ pUrlData->canonical = mprintf( "%s://%s%T%T%s", pUrlData->protocol, zLogin, pUrlData->name, pUrlData->path, zExe ); }else{ pUrlData->canonical = mprintf( "%s://%s%T:%d%T%s", pUrlData->protocol, zLogin, pUrlData->name, pUrlData->port, pUrlData->path, zExe ); } if( pUrlData->isSsh && pUrlData->path[1] ) pUrlData->path++; free(zLogin); }else if( strncmp(zUrl, "file:", 5)==0 ){ pUrlData->isFile = 1; if( zUrl[5]=='/' && zUrl[6]=='/' ){ i = 7; }else{ i = 5; } zFile = mprintf("%s", &zUrl[i]); }else if( file_isfile(zUrl) ){ pUrlData->isFile = 1; zFile = mprintf("%s", zUrl); }else if( file_isdir(zUrl)==1 ){ zFile = mprintf("%s/FOSSIL", zUrl); if( file_isfile(zFile) ){ pUrlData->isFile = 1; }else{ free(zFile); zFile = 0; fossil_fatal("unknown repository: %s", zUrl); } }else{ fossil_fatal("unknown repository: %s", zUrl); } if( urlFlags ) pUrlData->flags = urlFlags; if( pUrlData->isFile ){ Blob cfile; dehttpize(zFile); file_canonical_name(zFile, &cfile, 0); free(zFile); zFile = 0; pUrlData->protocol = "file"; pUrlData->path = ""; pUrlData->name = mprintf("%b", &cfile); pUrlData->canonical = mprintf("file://%T", pUrlData->name); blob_reset(&cfile); }else if( pUrlData->user!=0 && pUrlData->passwd==0 && (urlFlags & URL_PROMPT_PW) ){ url_prompt_for_password_local(pUrlData); }else if( pUrlData->user!=0 && ( urlFlags & URL_ASK_REMEMBER_PW ) ){ if( isatty(fileno(stdin)) ){ if( save_password_prompt(pUrlData->passwd) ){ pUrlData->flags = urlFlags |= URL_REMEMBER_PW; }else{ pUrlData->flags = urlFlags &= ~URL_REMEMBER_PW; } } } }
/* ** WEBPAGE: doc ** URL: /doc?name=BASELINE/PATH ** URL: /doc/BASELINE/PATH ** ** BASELINE can be either a baseline uuid prefix or magic words "tip" ** to mean the most recently checked in baseline or "ckout" to mean the ** content of the local checkout, if any. PATH is the relative pathname ** of some file. This method returns the file content. ** ** If PATH matches the patterns *.wiki or *.txt then formatting content ** is added before returning the file. For all other names, the content ** is returned straight without any interpretation or processing. */ void doc_page(void){ const char *zName; /* Argument to the /doc page */ const char *zMime; /* Document MIME type */ int vid = 0; /* Artifact of baseline */ int rid = 0; /* Artifact of file */ int i; /* Loop counter */ Blob filebody; /* Content of the documentation file */ char zBaseline[UUID_SIZE+1]; /* Baseline UUID */ login_check_credentials(); if( !g.perm.Read ){ login_needed(); return; } zName = PD("name", "tip/index.wiki"); for(i=0; zName[i] && zName[i]!='/'; i++){} if( zName[i]==0 || i>UUID_SIZE ){ zName = "index.html"; goto doc_not_found; } memcpy(zBaseline, zName, i); zBaseline[i] = 0; zName += i; while( zName[0]=='/' ){ zName++; } if( !file_is_simple_pathname(zName) ){ int n = strlen(zName); if( n>0 && zName[n-1]=='/' ){ zName = mprintf("%sindex.html", zName); if( !file_is_simple_pathname(zName) ){ goto doc_not_found; } }else{ goto doc_not_found; } } if( fossil_strcmp(zBaseline,"ckout")==0 && db_open_local()==0 ){ sqlite3_snprintf(sizeof(zBaseline), zBaseline, "tip"); } if( fossil_strcmp(zBaseline,"ckout")==0 ){ /* Read from the local checkout */ char *zFullpath; db_must_be_within_tree(); zFullpath = mprintf("%s/%s", g.zLocalRoot, zName); if( !file_isfile(zFullpath) ){ goto doc_not_found; } if( blob_read_from_file(&filebody, zFullpath)<0 ){ goto doc_not_found; } }else{ db_begin_transaction(); if( fossil_strcmp(zBaseline,"tip")==0 ){ vid = db_int(0, "SELECT objid FROM event WHERE type='ci'" " ORDER BY mtime DESC LIMIT 1"); }else{ vid = name_to_typed_rid(zBaseline, "ci"); } /* Create the baseline cache if it does not already exist */ db_multi_exec( "CREATE TABLE IF NOT EXISTS vcache(\n" " vid INTEGER, -- baseline ID\n" " fname TEXT, -- filename\n" " rid INTEGER, -- artifact ID\n" " UNIQUE(vid,fname,rid)\n" ")" ); /* Check to see if the documentation file artifact ID is contained ** in the baseline cache */ rid = db_int(0, "SELECT rid FROM vcache" " WHERE vid=%d AND fname=%Q", vid, zName); if( rid==0 && db_exists("SELECT 1 FROM vcache WHERE vid=%d", vid) ){ goto doc_not_found; } if( rid==0 ){ Stmt s; Manifest *pM; ManifestFile *pFile; /* Add the vid baseline to the cache */ if( db_int(0, "SELECT count(*) FROM vcache")>10000 ){ db_multi_exec("DELETE FROM vcache"); } pM = manifest_get(vid, CFTYPE_MANIFEST); if( pM==0 ){ goto doc_not_found; } db_prepare(&s, "INSERT INTO vcache(vid,fname,rid)" " SELECT %d, :fname, rid FROM blob" " WHERE uuid=:uuid", vid ); manifest_file_rewind(pM); while( (pFile = manifest_file_next(pM,0))!=0 ){ db_bind_text(&s, ":fname", pFile->zName); db_bind_text(&s, ":uuid", pFile->zUuid); db_step(&s); db_reset(&s); } db_finalize(&s); manifest_destroy(pM); /* Try again to find the file */ rid = db_int(0, "SELECT rid FROM vcache" " WHERE vid=%d AND fname=%Q", vid, zName); } if( rid==0 ){ goto doc_not_found; } /* Get the file content */ if( content_get(rid, &filebody)==0 ){ goto doc_not_found; } db_end_transaction(0); } /* The file is now contained in the filebody blob. Deliver the ** file to the user */ zMime = P("mimetype"); if( zMime==0 ){ zMime = mimetype_from_name(zName); } Th_Store("doc_name", zName); Th_Store("doc_version", db_text(0, "SELECT '[' || substr(uuid,1,10) || ']'" " FROM blob WHERE rid=%d", vid)); Th_Store("doc_date", db_text(0, "SELECT datetime(mtime) FROM event" " WHERE objid=%d AND type='ci'", vid)); if( fossil_strcmp(zMime, "application/x-fossil-wiki")==0 ){ Blob title, tail; if( wiki_find_title(&filebody, &title, &tail) ){ style_header(blob_str(&title)); wiki_convert(&tail, 0, 0); }else{ style_header("Documentation"); wiki_convert(&filebody, 0, 0); } style_footer(); }else if( fossil_strcmp(zMime, "text/plain")==0 ){ style_header("Documentation"); @ <blockquote><pre>
/* ** Parse the given URL. Populate variables in the global "g" structure. ** ** g.urlIsFile True if FILE: ** g.urlIsHttps True if HTTPS: ** g.urlIsSsh True if SSH: ** g.urlProtocol "http" or "https" or "file" ** g.urlName Hostname for HTTP:, HTTPS:, SSH:. Filename for FILE: ** g.urlPort TCP port number for HTTP or HTTPS. ** g.urlDfltPort Default TCP port number (80 or 443). ** g.urlPath Path name for HTTP or HTTPS. ** g.urlUser Userid. ** g.urlPasswd Password. ** g.urlHostname HOST:PORT or just HOST if port is the default. ** g.urlCanonical The URL in canonical form, omitting the password ** ** HTTP url format is: ** ** http://userid:password@host:port/path ** ** SSH url format is: ** ** ssh://userid:password@host:port/path?fossil=path/to/fossil.exe ** */ void url_parse(const char *zUrl){ int i, j, c; char *zFile = 0; if( strncmp(zUrl, "http://", 7)==0 || strncmp(zUrl, "https://", 8)==0 || strncmp(zUrl, "ssh://", 6)==0 ){ int iStart; char *zLogin; char *zExe; g.urlIsFile = 0; if( zUrl[4]=='s' ){ g.urlIsHttps = 1; g.urlProtocol = "https"; g.urlDfltPort = 443; iStart = 8; }else if( zUrl[0]=='s' ){ g.urlIsSsh = 1; g.urlProtocol = "ssh"; g.urlDfltPort = 22; g.urlFossil = "fossil"; iStart = 6; }else{ g.urlIsHttps = 0; g.urlProtocol = "http"; g.urlDfltPort = 80; iStart = 7; } for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!='@'; i++){} if( c=='@' ){ /* Parse up the user-id and password */ for(j=iStart; j<i && zUrl[j]!=':'; j++){} g.urlUser = mprintf("%.*s", j-iStart, &zUrl[iStart]); dehttpize(g.urlUser); if( j<i ){ g.urlPasswd = mprintf("%.*s", i-j-1, &zUrl[j+1]); dehttpize(g.urlPasswd); } if( g.urlIsSsh && g.urlPasswd ){ zLogin = mprintf("%t:*@", g.urlUser); }else{ zLogin = mprintf("%t@", g.urlUser); } for(j=i+1; (c=zUrl[j])!=0 && c!='/' && c!=':'; j++){} g.urlName = mprintf("%.*s", j-i-1, &zUrl[i+1]); i = j; }else{ for(i=iStart; (c=zUrl[i])!=0 && c!='/' && c!=':'; i++){} g.urlName = mprintf("%.*s", i-iStart, &zUrl[iStart]); zLogin = mprintf(""); } url_tolower(g.urlName); if( c==':' ){ g.urlPort = 0; i++; while( (c = zUrl[i])!=0 && fossil_isdigit(c) ){ g.urlPort = g.urlPort*10 + c - '0'; i++; } g.urlHostname = mprintf("%s:%d", g.urlName, g.urlPort); }else{ g.urlPort = g.urlDfltPort; g.urlHostname = g.urlName; } dehttpize(g.urlName); g.urlPath = mprintf("%s", &zUrl[i]); for(i=0; g.urlPath[i] && g.urlPath[i]!='?'; i++){} if( g.urlPath[i] ){ g.urlPath[i] = 0; i++; } zExe = mprintf(""); while( g.urlPath[i]!=0 ){ char *zName, *zValue; zName = &g.urlPath[i]; zValue = zName; while( g.urlPath[i] && g.urlPath[i]!='=' ){ i++; } if( g.urlPath[i]=='=' ){ g.urlPath[i] = 0; i++; zValue = &g.urlPath[i]; while( g.urlPath[i] && g.urlPath[i]!='&' ){ i++; } } if( g.urlPath[i] ){ g.urlPath[i] = 0; i++; } if( fossil_strcmp(zName,"fossil")==0 ){ g.urlFossil = zValue; dehttpize(g.urlFossil); zExe = mprintf("?fossil=%T", g.urlFossil); } } dehttpize(g.urlPath); if( g.urlDfltPort==g.urlPort ){ g.urlCanonical = mprintf( "%s://%s%T%T%s", g.urlProtocol, zLogin, g.urlName, g.urlPath, zExe ); }else{ g.urlCanonical = mprintf( "%s://%s%T:%d%T%s", g.urlProtocol, zLogin, g.urlName, g.urlPort, g.urlPath, zExe ); } if( g.urlIsSsh && g.urlPath[1] ) g.urlPath++; free(zLogin); }else if( strncmp(zUrl, "file:", 5)==0 ){ g.urlIsFile = 1; if( zUrl[5]=='/' && zUrl[6]=='/' ){ i = 7; }else{ i = 5; } zFile = mprintf("%s", &zUrl[i]); }else if( file_isfile(zUrl) ){ g.urlIsFile = 1; zFile = mprintf("%s", zUrl); }else if( file_isdir(zUrl)==1 ){ zFile = mprintf("%s/FOSSIL", zUrl); if( file_isfile(zFile) ){ g.urlIsFile = 1; }else{ free(zFile); fossil_panic("unknown repository: %s", zUrl); } }else{ fossil_panic("unknown repository: %s", zUrl); } if( g.urlIsFile ){ Blob cfile; dehttpize(zFile); file_canonical_name(zFile, &cfile, 0); free(zFile); g.urlProtocol = "file"; g.urlPath = ""; g.urlName = mprintf("%b", &cfile); g.urlCanonical = mprintf("file://%T", g.urlName); blob_reset(&cfile); } }