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

📄 html-ls-server.c

📁 linux下网络编程
💻 C
字号:
/* html-ls-server.c
 *
 * Copyright (c) 2000 Sean Walton and Macmillan Publishers.  Use may be in
 * whole or in part in accordance to the General Public License (GPL).
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
*/

/*****************************************************************************/
/*** html-ls-server.c (multitasking)                                       ***/
/***                                                                       ***/
/*** Multitask directory listing server (HTTP).                          ***/
/*****************************************************************************/

#include <stdarg.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <resolv.h>
#include <arpa/inet.h>

#define	MY_PORT		9999

void PERROR(char* msg);
#define PERROR(msg)	{ perror(msg); abort(); }
#define MAXBUF	1024
char buffer[MAXBUF];
char *Host="127.0.0.1:9999";

#define MAXPATH	150
/*---------------------------------------------------------------------*/
/*--- strtrim - trim the spaces off the front and back of a string. ---*/
/*---------------------------------------------------------------------*/
char* strtrim(char *str)
{	int tail=strlen(str);
	while ( str[tail] <= ' '  &&  tail > 0 )
		tail--;
	str[tail+1] = 0;
	while ( *str <= ' '  &&  *str != 0 )
		str++;
	return str;
}

/*---------------------------------------------------------------------*/
/*--- panic - report error and die.                                 ---*/
/*---------------------------------------------------------------------*/
void panic(char* msg, ...)
{	va_list ap;

	va_start(ap, msg);
	vprintf(msg, ap);
	va_end(ap);
	exit(0);
}

/*---------------------------------------------------------------------*/
/*--- dir_up - find the parent directory in a path.                 ---*/
/*---------------------------------------------------------------------*/
char* dir_up(char* dirpath)
{   static char Path[MAXPATH];
	int len;

	strcpy(Path, dirpath);
	len = strlen(Path);
	if ( len > 1  &&  Path[len-1] == '/' )
		len--;
	while ( Path[len-1] != '/'  &&  len > 1 )
		len--;
	Path[len] = 0;
	return Path;
}

#define MAXNAME	25

/*---------------------------------------------------------------------*/
/*--- DirListing - read the directory and output an HTML table      ---*/
/*---------------------------------------------------------------------*/
void DirListing(FILE* FP, char* Path)
{	struct dirent *dirent;
	struct stat info;
	char Filename[MAXPATH];
	DIR* dir = opendir(Path);
	fprintf(FP, "<html><head><title>Directory Lister</title></body>"
		"<body><font size=+4>Linux Directory Server</font><br><hr width=\"100%%\"><br><center>"
		"<table border cols=4 width=\"100%%\" bgcolor=\"#33CCFF\">");
	fprintf(FP, "<caption><font size=+3>Directory of %s</font></caption>\n", Path);
	if ( dir == 0 )
	{
		fprintf(FP, "</table><font color=\"CC0000\" size=+2>%s</font></body></html>", strerror(errno));
		return;
	}
	while ( (dirent = readdir(dir)) != 0 )
	{
		if ( strcmp(Path, "/") == 0 )
			sprintf(Filename, "/%s", dirent->d_name);
		else
			sprintf(Filename, "%s/%s", Path, dirent->d_name);
		fprintf(FP, "<tr>");
		if ( stat(Filename, &info) == 0 )
		{
			fprintf(FP, "<td>%s</td>", dirent->d_name);
			if ( S_ISDIR(info.st_mode) )
			{
				if ( strcmp(dirent->d_name, "..") == 0 )
					fprintf(FP, "<td><a href=\"http://%s%s\">(parent)</a></td>", Host, dir_up(Path));
				else
					fprintf(FP, "<td><a href=\"http://%s%s\">%s</a></td>", Host, Filename, dirent->d_name);
				fprintf(FP, "<td>Directory</td>");
			}
			else if ( S_ISREG(info.st_mode) )
			{
				fprintf(FP, "<td><a href=\"ftp://%s%s\">%s</a></td>", Host, Filename, dirent->d_name);
				fprintf(FP, "<td>%d</td>", info.st_size);
			}
			else if ( S_ISLNK(info.st_mode) )
				fprintf(FP, "<td>Link</td>");
			else if ( S_ISCHR(info.st_mode) )
				fprintf(FP, "<td>Character Device</td>");
			else if ( S_ISBLK(info.st_mode) )
				fprintf(FP, "<td>Block Device</td>");
			else if ( S_ISFIFO(info.st_mode) )
				fprintf(FP, "<td>FIFO</td>");
			else if ( S_ISSOCK(info.st_mode) )
				fprintf(FP, "<td>Socket</td>");
			else
				fprintf(FP, "<td>(unknown)</td>");
			fprintf(FP, "<td>%s</td>", strtrim(ctime(&info.st_ctime)));
		}
		else
			perror(Path);
		fprintf(FP, "</tr>\n");
	}
	fprintf(FP, "</table></center></body></html>");
}

/*---------------------------------------------------------------------*/
/*--- main - set up client and accept connections.                  ---*/
/*---------------------------------------------------------------------*/
int main(void)
{	struct sockaddr_in addr;
	int sd, addrlen = sizeof(addr);

	if ( (sd = socket(PF_INET, SOCK_STREAM, 0)) < 0 )
		PERROR("Socket");
	addr.sin_family = AF_INET;
	addr.sin_port = htons(MY_PORT);
	addr.sin_addr.s_addr = INADDR_ANY;
	if ( bind(sd, (struct sockaddr*)&addr, addrlen) < 0 )
		PERROR("Bind");
	if ( listen(sd, 20) < 0 )
		PERROR("Listen");
	while (1)
	{	int len;
		int client = accept(sd, (struct sockaddr*)&addr, &addrlen);
		printf("Connected: %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));

		if ( (len = recv(client, buffer, MAXBUF, 0)) > 0 )
		{
			FILE* ClientFP = fdopen(client, "w");
			if ( ClientFP == NULL )
				perror("fpopen");
			else
			{	char Req[MAXPATH];
				sscanf(buffer, "GET %s HTTP", Req);
				printf("Request: \"%s\"\n", Req);
				DirListing(ClientFP, Req);
				fclose(ClientFP);
			}
		}
		close(client);
	}
	return 0;
}

⌨️ 快捷键说明

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