Ejemplo n.º 1
0
/*******************************************************************
 *	FileName: 要送出去的檔案名稱
 *
 *	如果是圖形或是其他類型檔案直接送出
 *	如果是 HTML 形式檔案則分析出 tag 將其代入適當的資料
 *******************************************************************/
int ShowFile(SKIN_FILE *sf)
{
	FILE *fp;
	int cache_idx;
	char type[STRLEN], tag[512];
	char pbuf[HTTP_REQUEST_LINE_BUF];

#if 0
	fprintf(fp_out, "ShowFile=%s", sf->filename);
	fflush(fp_out);
#endif

	if (sf->mime_type > 1)	/* 不是HTML, 不用處理 WEBBBS tag, 直接送出去 */
	{
		if((cache_idx = CacheState(sf->filename, NULL)) == -1
		|| difftime(file_shm[cache_idx].file.mtime, sf->mtime) != 0)
			cache_idx = do_cache_file(sf->filename);

		if(cache_idx != -1)		/* file is cached */
		{
			file_shm[cache_idx].atime = request_rec->atime;
			file_shm[cache_idx].hit++;
			write(STDOUT_FILENO, file_shm[cache_idx].data, file_shm[cache_idx].file.size);
		}
		else
		{
			int size;

			if((fp = fopen(sf->filename, "rb")) == NULL)
				return FALSE;

			while((size = fread(pbuf, 1, sizeof(pbuf), fp)) != 0 )
				fwrite(pbuf, 1, size, fp_out);

			fclose(fp);
		}
	}
	else	/* html file, should process it */
	{
		if((cache_idx = CacheState(sf->filename, NULL)) == -1
		|| difftime(html_shm[cache_idx].file.mtime, sf->mtime) != 0)
			cache_idx = do_cache_html(sf->filename);
#if 0
		fprintf(fp_out, "cache_idx = %d", cache_idx);
		fflush(fp_out);
#endif

		if(cache_idx != -1)		/* file is cached */
		{
			int i;

			html_shm[cache_idx].atime = request_rec->atime;
			html_shm[cache_idx].hit++;

			for(i=0; html_shm[cache_idx].format[i].type; i++)
			{
				if(html_shm[cache_idx].format[i].type == 'S')
				{
					fwrite(html_shm[cache_idx].data+html_shm[cache_idx].format[i].offset, sizeof(char), (html_shm[cache_idx].format[i+1].offset)-(html_shm[cache_idx].format[i].offset), fp_out);
				}
				else
				{
					xstrncpy(pbuf, html_shm[cache_idx].data+html_shm[cache_idx].format[i].offset, (html_shm[cache_idx].format[i+1].offset)-(html_shm[cache_idx].format[i].offset)+1);
					GetBBSTag(type, tag, pbuf);
					DoTagCommand(type, tag);
				}
			}

		}
		else
		{
			char *p, *data, *next;

			if ((fp = fopen(sf->filename, "r")) == NULL)
				return FALSE;

			while (fgets(pbuf, sizeof(pbuf), fp) != NULL)
			{
				if ((p = strchr(pbuf, '\n')) != NULL)
					*p = '\0';
				data = pbuf;

				while(1)	/* process WEBBBS TAG */
				{
					if((next = GetBBSTag(type, tag, data)) != NULL)
					{
						fprintf(fp_out, "%s", data);
						data = next;
						DoTagCommand(type, tag);
					}
					else
					{
						fprintf(fp_out, "%s\n", data);
						break;
					}
				}
			}

			fclose(fp);
		}
	}

	return TRUE;
}
Ejemplo n.º 2
0
Archivo: bbsweb.c Proyecto: wtj/formosa
/*******************************************************************
 *	根據 URLParaType 執行 GET 的要求
 *
 *	
 *	return WebRespondType
 *******************************************************************/
int 
DoGetRequest(REQUEST_REC * rc, BOARDHEADER * board, POST_FILE * pf)
{
	char *p, *boardname;
	int URLParaType = rc->URLParaType;
	char fname[PATHLEN];

	boardname = board->filename;

	if (URLParaType == Redirect)
	{
		/* redirect target must set in ParseURI() */
		return WEB_REDIRECT;
	}

	if (PSCorrect != Correct
	    && (URLParaType == MailList
		|| URLParaType == MailRead
		|| URLParaType == SkinModify))
	{
		return WEB_USER_NOT_LOGIN;
	}

	if (URLParaType == PostList
	    || URLParaType == PostRead
	    || URLParaType == TreaList
	    || URLParaType == TreaRead
	    || URLParaType == SkinModify
	    || URLParaType == Board)
	{
		int perm;

		if (get_board(board, boardname) <= 0 || board->filename[0] == '\0')
			return WEB_BOARD_NOT_FOUND;

		if ((perm = CheckBoardPerm(board, &curuser)) != WEB_OK)
			return perm;

		if (board->brdtype & BRD_WEBSKIN)	/* Board has custom html skin */
		{
			char *skin, web_board_dir[PATHLEN];

			if (URLParaType == SkinModify)
			{
				if (strlen(pf->POST_NAME) != 0)
				{
					xstrncpy(web_board_dir, pf->POST_NAME, PATHLEN);
					skin = strrchr(web_board_dir, '/') + 1;
					setskinfile(pf->POST_NAME, boardname, skin);
				}
			}
			else if (!strstr(skin_file->filename, HTML_BoardModify))
			{
				/* set specfic skin file to custom file */
				xstrncpy(web_board_dir, skin_file->filename, PATHLEN);
				skin = strrchr(web_board_dir, '/') + 1;
				setskinfile(skin_file->filename, boardname, skin);
			}
		}
		else
		{
			if (strstr(skin_file->filename, HTML_SkinModify))
				return WEB_FILE_NOT_FOUND;
		}
	}

	if (strstr(skin_file->filename, HTML_BoardModify)
	    && (!HAS_PERM(PERM_SYSOP) || PSCorrect != Correct))
	{
		return WEB_FILE_NOT_FOUND;
	}

	switch (URLParaType)
	{
		case TreaRead:
		case PostRead:
			if (GetPostInfo(board, pf) != WEB_OK)
				return WEB_FILE_NOT_FOUND;

			break;

		case TreaList:
		case PostList:
			pf->total_rec = get_num_records(pf->POST_NAME, FH_SIZE);

			break;

		case MailList:
			if (PSCorrect == Correct)
				pf->total_rec = get_num_records(pf->POST_NAME, FH_SIZE);
			else
				pf->total_rec = 0;
			break;

		case MailRead:
			if (PSCorrect == Correct)
			{
				int RESULT = GetPostInfo(board, pf);

				if (RESULT != WEB_OK)
					return RESULT;
			}
			break;

		case UserList:
		case BoardList:
		case TreaBoardList:
		case UserData:
		case SkinModify:
			/* do nothing here.. */

			break;

		case UserQuery:
			/* put USER_REC in curuser for query */
			if (!get_passwd(&curuser, username))
			{
				bzero(&curuser, sizeof(USEREC));
				return WEB_USER_NOT_FOUND;
			}
			break;

		case Board:	/* cuscom webboard */
		case Mail:	/* ?? */
#if 0
			fprintf(fp_out, "DoGetRequest Board,Mail:[%s]", skin_file->filename);
			fflush(fp_out);
#endif
			if (CacheState(skin_file->filename, NULL) < 0
			    && !isfile(skin_file->filename))
			{
				return WEB_FILE_NOT_FOUND;
			}
			break;

		default:
#if 0
			fprintf(fp_out, "DoGetRequest default:[%s]\r\n", skin_file->filename);
			fflush(fp_out);
#endif

			xstrncpy(fname, skin_file->filename, sizeof(fname));

			if (isBadURI(fname))
			{
				BBS_SUBDIR[0] = 0x00;
				return WEB_BAD_REQUEST;
			}

			sprintf(skin_file->filename, "%s%s", HTML_PATH, fname + 1);

			if (CacheState(skin_file->filename, NULL) == -1)	/* file not in cache */
			{
				if (isdir(skin_file->filename))
				{
					p = skin_file->filename + strlen(skin_file->filename) - 1;
					if (*p == '/')
					{
						strcat(skin_file->filename, DEFAULT_HTML);
					}
					else
					{
						sprintf(skin_file->filename, "%s/", fname);
						return WEB_REDIRECT;
					}
				}
				else
				{
					if ((p = strrchr(fname + 1, '/')) == NULL)
						p = fname;
					if (!strcmp(p, "/boards")
					    || !strcmp(p, "/treasure")
					    || !strcmp(p, "/mail")
					    || !strcmp(p, "/users"))
					{
						sprintf(skin_file->filename, "%s/", fname);
						return WEB_REDIRECT;
					}
				}

				if (!isfile(skin_file->filename))
				{
					BBS_SUBDIR[0] = 0x00;
					return WEB_FILE_NOT_FOUND;
				}
			}

#ifdef WEB_LOGIN_CHECK
			return WebLoginCheck();
#endif

	}

	return WEB_OK;

}
Ejemplo n.º 3
0
/*******************************************************************
 *	從 URI 判斷要求及抓出有用的資訊
 *	set BOARDNAME, POST_NAME, SKIN_FILE
 *
 *	return URLParaType
 *******************************************************************/
int ParseURI(const char *curi, REQUEST_REC *r, BOARDHEADER *board, POST_FILE *pf)
{
	char *p, *boardname;
	int HttpRequestType;
	char skin[PATHLEN], post[PATHLEN];

	*skin = 0x00;
	*post = 0x00;
	*BBS_SUBDIR = 0x00;

	boardname = board->filename;
	HttpRequestType = r->HttpRequestType;


	if(curi[strlen(curi)-1] == '\\')
	{
		strncat(skin_file->filename, curi, strlen(curi)-1);
		return Redirect;
	}
	else if((p = strstr(curi, "/treasure/")) != NULL)
	{
		/*
			subdir/treasure/bname/
			subdir/treasure/bname/start-end
			subdir/treasure/bname/treadir/treapost
		*/

		xstrncpy(BBS_SUBDIR, curi+1, p-curi+1);
		curi = p + 10;
	#if 0
		if(curi[strlen(curi)-1] == '\\')
		{
			sprintf(skin_file->filename, "/%streasure/", BBS_SUBDIR);
			strncat(skin_file->filename, curi, strlen(curi)-1);
			return Redirect;
		}
	#endif
		GetURIToken(boardname, post, skin, curi);

#if 0
		fprintf(fp_out, "[BOARDNAME=%s, post=%s, skin=%s]<br>", boardname, post, skin);
		fflush(fp_out);
#endif

		if(HttpRequestType == POST)
		{
			xstrncpy(pf->POST_NAME, post, PATHLEN);

			if(!strcmp(skin, POST_PostSend))
				return TreaSend;
			else if(!strcmp(skin, POST_PostEdit))
				return TreaEdit;
			else if(!strcmp(skin, POST_PostForward))
				return TreaForward;
			else if(!strcmp(skin, POST_PostDelete))
				return TreaDelete;
			else
				return Board;
		}

		if(strlen(boardname)==0)	/* no BOARDNAME assigned , list all boards */
		{
			if(strlen(skin)==0)
			{
				sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_TreaBoardList);
				return TreaBoardList;
			}
			else
			{
				/* skin is boardname */
				sprintf(skin_file->filename, "/%streasure/%s/", BBS_SUBDIR, skin);
				return Redirect;
			}
		}

		if(strlen(skin)==0)		/* must be treasure dir */
		{
			if(strlen(post)==0)
			{
				settreafile(pf->POST_NAME, board->filename, DIR_REC);
			}
			else
			{
				settreafile(pf->POST_NAME, board->filename, post);
				strcat(pf->POST_NAME, "/");
				strcat(pf->POST_NAME, DIR_REC);
			}

			sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_TreaList);
			return TreaList;
		}

		if(strlen(post))	/* has treasure sub-dir*/
		{
			settreafile(pf->POST_NAME, boardname, post);
			strcat(pf->POST_NAME, "/");
			strcat(pf->POST_NAME, skin);
		}
		else
		{
			settreafile(pf->POST_NAME, boardname, skin);
		}

		if(isPost(skin))
		{
			strip_html(pf->POST_NAME);
			sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_TreaPost);
			return TreaRead;
		}

		if(isdir(pf->POST_NAME))	/* check isdir before isPost */
		{
			sprintf(skin_file->filename, "/%s%s/", BBS_SUBDIR, pf->POST_NAME);
			return Redirect;
		}

		sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, skin);
		if(CacheState(skin_file->filename, NULL) >=0
		|| isfile(skin_file->filename))
		{
			if(strlen(post)==0)
				return TreaList;

			settreafile(pf->POST_NAME, board->filename, post);
			return TreaRead;
		}

		if(isList(skin, &(pf->list_start), &(pf->list_end)))
		{
			if(strlen(post)==0)
				settreafile(pf->POST_NAME, board->filename, DIR_REC);
			else
				sprintf(pf->POST_NAME, "treasure/%s/%s/%s", boardname, post, DIR_REC);

			sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_TreaList);
			return TreaList;
		}
		else
		{
			settreafile(skin_file->filename, boardname, skin);
			return Board;
		}

	}
	else if((p = strstr(curi, "/boards/")) != NULL)
	{
		/*
			subdir/board/bname/
			subdir/board/bname/start-end
			subdir/board/bname/post
		*/

		xstrncpy(BBS_SUBDIR, curi+1, p-curi+1);
		curi = p + 8;

		GetURIToken(boardname, post, skin, curi);

#if 0
		fprintf(fp_out, "[BOARDNAME=%s, post=%s, skin=%s]<br>", boardname, post, skin);
		fflush(fp_out);
#endif

		if(HttpRequestType == POST)
		{
			xstrncpy(pf->POST_NAME, post, PATHLEN);

			if(!strcmp(skin, POST_PostSend))
				return PostSend;
			else if(!strcmp(skin, POST_PostEdit))
				return PostEdit;
			else if(!strcmp(skin, POST_PostForward))
				return PostForward;
			else if(!strcmp(skin, POST_PostDelete))
				return PostDelete;
			else if(!strcmp(skin, POST_BoardModify))
				return BoardModify;
			else if(!strcmp(skin, POST_SkinModify))
				return SkinModify;
			else if(!strcmp(skin, POST_AccessListModify))
				return AccessListModify;
			else
				return Board;
		}

		if(strlen(boardname)==0)
		{
			/* case:
				/boards/
				/boards/boardname
			*/

			if(strlen(skin)==0)
			{
				sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_BoardList);
				return BoardList;
			}
			else
			{
				/* skin is boardname */
				sprintf(skin_file->filename, "/%sboards/%s/", BBS_SUBDIR, skin);
				return Redirect;
			}
		}

		if(strlen(skin)==0)
		{
			/* case: /boards/boardname/ */

			sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_PostList);
			setboardfile(pf->POST_NAME, boardname, DIR_REC);
			return PostList;
		}

		if(isList(skin, &(pf->list_start), &(pf->list_end)))
		{
			setboardfile(pf->POST_NAME, board->filename, DIR_REC);
			sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_PostList);
			return PostList;
		}

		if(isPost(skin))
		{
			strip_html(skin);

			setboardfile(pf->POST_NAME, boardname, skin);
			sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_Post);
			return PostRead;
		}

		sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, skin);

		if(CacheState(skin_file->filename, NULL) >=0
		|| isfile(skin_file->filename))
		{
			if(strlen(post)==0)		/* is DIR_REC skin */
			{
				if(!strcmp(skin, HTML_SkinModify))
				{
					*(pf->POST_NAME) = '\0';
					return SkinModify;
				}
				else
				{
					setboardfile(pf->POST_NAME, boardname, DIR_REC);
					return PostList;
				}
			}
			else					/* is post skin */
			{
				sprintf(pf->POST_NAME, "%s%s%s", HTML_PATH, BBS_SUBDIR, post);

				if(isfile(pf->POST_NAME))
				{
					sprintf(pf->POST_NAME, "%s%s%s", HTML_PATH, BBS_SUBDIR, post);
					return SkinModify;
				}
				else
				{
					setboardfile(pf->POST_NAME, board->filename, post);
					return PostRead;
				}
			}
		}

		setboardfile(skin_file->filename, boardname, skin);
		return Board;

	}
	else if((p = strstr(curi, "/mail/")) != NULL)
	{
		xstrncpy(BBS_SUBDIR, curi+1, p-curi+1);
		curi = p + 6;

		GetURIToken(boardname, post, skin, curi);

#if 0
		fprintf(fp_out, "[BOARDNAME=%s, post=%s, skin=%s]<br>", boardname, post, skin);
		fflush(fp_out);
#endif

		if(HttpRequestType == POST)
		{
			xstrncpy(pf->POST_NAME, boardname, PATHLEN);

			if(!strcmp(skin, POST_MailSend))
				return MailSend;
			else if(!strcmp(skin, POST_MailForward))
				return MailForward;
			else if(!strcmp(skin, POST_MailDelete))
				return MailDelete;
			else
				return OtherFile;
		}

		/* !! 'BOARDNAME' is 'post' in this section !! */
#if 0
		if(strlen(boardname)==0 && strlen(skin)==0)
		{
			sprintf(skin_file->filename, "%s%s", BBS_SUBDIR, HTML_MailList);
			setmailfile(pf->POST_NAME, username, DIR_REC);
			return MailList;
		}
#endif

		if(strlen(skin)==0)
		{
			sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_MailList);
			setmailfile(pf->POST_NAME, username, DIR_REC);
			return MailList;
		}

		if(isList(skin, &(pf->list_start), &(pf->list_end)))
		{
			setmailfile(pf->POST_NAME, username, DIR_REC);
			sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_MailList);
			return MailList;
		}

		if(isPost(skin))
		{
			strip_html(skin);
			setmailfile(pf->POST_NAME, username, skin);
			sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_Mail);
			return MailRead;
		}

		sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, skin);

		if(CacheState(skin_file->filename, NULL) >=0
		|| isfile(skin_file->filename))
		{
			if(strlen(board->filename) != 0)
			{
				setmailfile(pf->POST_NAME, username, boardname);
				return MailRead;
			}
			else
			{
				setmailfile(pf->POST_NAME, username, DIR_REC);
				return MailList;
			}
		}

		setmailfile(skin_file->filename, username, skin);
		return Mail;

	}
	else if((p = strstr(curi, "/users/")) != NULL)
	{
		xstrncpy(BBS_SUBDIR, curi+1, p-curi+1);
		curi = p + 7;

		GetURIToken(board->filename, post, skin, curi);

#if 0
		fprintf(fp_out, "[BOARDNAME=%s, post=%s, skin=%s]", board->filename, post, skin);
		fflush(fp_out);
#endif
		if(HttpRequestType == POST)
		{
			if(!strcmp(skin, POST_UserNew))
				return UserNew;
			else if(!strcmp(skin, POST_UserIdent))
				return UserIdent;
			else if(!strcmp(skin, POST_UserData))
				return UserData;
			else if(!strcmp(skin, POST_UserPlan))
				return UserPlan;
			else if(!strcmp(skin, POST_UserSign))
				return UserSign;
			else if(!strcmp(skin, POST_UserFriend))
				return UserFriend;
			else
				return OtherFile;
		}

		if(strlen(skin)==0)
		{
			if(strlen(board->filename)!=0)
			{
				xstrncpy(username, board->filename, IDLEN);
				sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_UserQuery);
				return UserQuery;
			}
			else
			{
				sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_UserList);
				return UserList;
			}
		}

		if(isList(skin, &(pf->list_start), &(pf->list_end)))
		{
			sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_UserList);
			return UserList;
		}

		sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, skin);

		if(CacheState(skin_file->filename, NULL) >=0
		|| isfile(skin_file->filename))
			return UserData;

		xstrncpy(username, skin, IDLEN);
		sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_UserQuery);
		return UserQuery;

	}
	else if(!strncmp(curi, "/~", 2))	/* want user planfile only */
	{

		curi+=2;
#if 0
		fprintf(fp_out, "userplan name=%s ", curi);
		fflush(fp_out);
#endif

		xstrncpy(username, curi, IDLEN);
		strtok(username, " /\t\r\n");
		sprintf(skin_file->filename, "%s%s", HTML_PATH, HTML_UserPlanShow);

		return UserQuery;

	}
	else
	{
#if 0
		fprintf(fp_out, "[other file=%s]", curi);
		fflush(fp_out);
#endif

#ifdef NSYSUBBS
		/* for compatiable with old URL parameter ================== */
		if((p = strstr(curi, "BoardName=")) != NULL
		|| (p = strstr(curi, "boardname=")) != NULL)
		{
			p+=10;
			strtok(p, "?&/");
			sprintf(skin_file->filename, "/txtVersion/boards/%s/", p);
			return Redirect;
		}
		/* ========================================================= */
#endif
		xstrncpy(skin_file->filename, curi, PATHLEN);
		xstrncpy(BBS_SUBDIR, curi+1, PATHLEN);
		if((p = strrchr(BBS_SUBDIR, '/')) != NULL)
			*(p+1) = 0x00;
		else
			BBS_SUBDIR[0] = 0x00;

		return OtherFile;

	}
}