📄 webserver.c
字号:
/*
*
* Emdedded web server for PPC860
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <sys/stat.h>
#include <dirent.h>
#include <signal.h>
#include <unistd.h>
#include <ctype.h>
int TIMEOUT = 30;//time delay setting
/* file type to be used*/
int TEXT = 1;
int HTML = 2;
int GIF = 3;
//unsigned short FILE_LENGTH = 32768;
//char file_buffer[32768];//[FILE_LENGTH];
//conditional compiling instruction
#ifndef O_BINARY
#define O_BINARY 0
#endif
char referrer[128];//this stores which page is the information linked
//to current resource come from.
int content_length;//the length of the stored file.
#define SERVER_PORT 80//specified server port
//#define DIR_OF_HTML "/htdocs"
#define DEBUG 1
// print the head of files
int PrintHeader(FILE *f, int type)
{
#ifdef DEBUG
printf("In Printheader \n");
#endif
alarm(TIMEOUT);
fprintf(f,"HTTP/1.0 200 OK\n");
if (type == TEXT)
fprintf(f,"Content-type: text/plain\n");
else if (type == HTML)
fprintf(f,"Content-type: text/html\n");
else
fprintf(f,"Content-type: image/gif\n");
/*fprintf(f,"Date:Sun, 10 ,8 ,2004 12:00:00 BeiJingTime\n");*/
fprintf(f,"Server:ipserver-http 0.0.1\n");
fprintf(f,"Expires:0\n");
fprintf(f,"\n");
alarm(0);
return 0;
}
int DoGif(FILE *f,char *name)//sent GIF format picture
{
char gifBuffer[BUFSIZ];
int count;
FILE* infile;
if(!(infile = fopen(name,"r")))//open name file with read mode
{
alarm(TIMEOUT);
fprintf(f,"Unable to open GIF file %s,%d\n",name,errno);
fflush(f);
alarm(0);
return -1;
}
PrintHeader(f, GIF);
alarm(TIMEOUT);
count = fread(gifBuffer, sizeof(char), BUFSIZ, infile);
alarm(0);
#ifdef DEBUG
printf(" <%d> bytes read from file: %s\n", count, name);
#endif
alarm(TIMEOUT);
fwrite(gifBuffer, sizeof(char), count, f);
alarm(0);
#ifdef DEBUG
printf(" After fwrite()......\n");
#endif
alarm(TIMEOUT);
fclose(infile);
alarm(0);
return 0;
}
int DoDir(FILE* f,char* name)
{
DIR* dir;
struct dirent* dirent;//dir structure
//open dir list
if((dir = opendir(name)) == 0)
{
fprintf(f,"Unable to open directory %s, %d\n",name,errno);
fflush(f);
return -1;
}
PrintHeader(f, HTML);
alarm(TIMEOUT);
fprintf(f,"<H1>Index of %s</H1)\n\n",name);//sent to browser the information
//of Index of
alarm (0);
//sent the dir information
while((dirent = readdir(dir)) != 0)
{
alarm(TIMEOUT);
#if 0
if(dirent->d_name[0] == '.')
continue;
#endif
if(name)
fprintf(f,"<p><a href=\"/...%s/%s\">%s</a></p>\n",name,
dirent->d_name,dirent->d_name);
else
fprintf(f,"<p><a href=\"/.../%s\">%s</a></p>\n",
dirent->d_name,dirent->d_name);
alarm(0);
}
closedir(dir);
return 0;
}
int DoHTML(FILE* f,char* name) //fadeback the HTML file information
{
char htmlBuffer[BUFSIZ];
int count;
FILE* infile;
char* dir = 0;
#ifdef DEBUG
printf(" name = <%s>\n", name);
#endif
if(!(infile = fopen(name,"r")))
{
alarm(TIMEOUT);
fprintf(f,"Unable to open HTML file %s\n",name);
fprintf(f,"<p>File'%s'not found (error %d)</p>\n",name,errno);
fflush(f);
alarm(0);
// DoDir(f, "/htdocs");
return -1;
}
PrintHeader(f, HTML);
if(dir == strrchr(name,'/'))
{
*dir = '\0';
chdir(name);
}
alarm(TIMEOUT);
count = fread(htmlBuffer, sizeof(char), BUFSIZ, infile);
alarm(0);
#ifdef DEBUG
printf(" <%d> bytes read from file: %s\n", count, name);
#endif
alarm(TIMEOUT);
fwrite(htmlBuffer, sizeof(char), count, f);
alarm(0);
#ifdef DEBUG
printf(" After fwrite()......\n");
#endif
if(dir)
{
chdir("/htdocs");
}
alarm(TIMEOUT);
fclose(infile);
alarm(0);
return 0;
}
int DoText(FILE* f ,char* name)
{
char textBuffer[BUFSIZ];
int count;
FILE * infile; //FILE is a pointer as file format,it pointed to
//an open file.
if(!(infile = fopen(name,"r")))
{
alarm(TIMEOUT);
fprintf(f,"Unable to open HTML file %s, %d\n",name,errno);
fflush(f);
alarm(0);
return -1;
}
PrintHeader(f, TEXT);
alarm(TIMEOUT);
count = fread(textBuffer, sizeof(char), BUFSIZ, infile);
alarm(0);
#ifdef DEBUG
printf(" <%d> bytes read from file: %s\n", count, name);
#endif
alarm(TIMEOUT);
fwrite(textBuffer, sizeof(char), count, f);
alarm(0);
#ifdef DEBUG
printf(" After fwrite()......\n");
#endif
alarm(TIMEOUT);
fclose(infile);
alarm(0);
return 0;
}
int ParseReq(FILE* f,char* r) //deal with request information
{
char * bp;
struct stat stbuf;
char* c;
// char* arg;
// char* e;
char* end;
#ifdef DEBUG
printf("\nRequest is %s\n",r);
#endif
while(*(++r)!= ' ');
// while(isspace(*r))//jump over blank
// r++;
// while(*r == '/')
// r++; //jump over '/'
bp = r;//bp pointed to the head of source address char
// *r = '.';
while(*r && (*(r) != ' ') && (*(r) != '?'))
r++;
#ifdef DEBUG
// printf("URL = %s", bp);
printf(" r = %s", r);
#endif
/*********************************
// if(*r == '?')
if(strchr(r, '?') != NULL)
{
*r = '\0'; //set it's content to be an ending mark
arg = r + 1; //arg point to the following one char
if((e = strchr(arg,' ')) != NULL)
*e = '\0'; //set to be ending mark
}
else
{
*arg = '\0';//no data input by user
*r = '\0';//the ending mark
}
********************************/
c = strtok(bp, " ");
#ifdef DEBUG
printf(" URL = <%s>\n", c);
#endif
if(c && !stat(c, &stbuf)) //c exist and also in stbuf too
{
if(strstr(c,".gif") != NULL)
{
#ifdef DEBUG
printf("Before DoGif");
#endif
DoGif(f,c);
}
else if(((strstr(c, ".html") != NULL) || (strstr(c, ".htm") != NULL)))
{
#ifdef DEBUG
printf(" Before Dohtml--last");
#endif
DoHTML(f,c);
}
/* else if(*c == 0)
{
strcat(c,"index.html");
if(!stat(c,&stbuf))
DoHTML(f,c);
}*/
//#ifdef DEBUG
// printf("Before DoHTML(1) c = <%s>\n", c);
//#endif
else if(S_ISDIR(stbuf.st_mode))
{
#ifdef DEBUG
printf("In the 2nd if c = <%s>\n", c);
#endif
end = c + strlen(c); //end if string
strcat(c,"index.html");
#ifdef DEBUG
printf(" c = <%s>\n", c);
#endif
// if(!stat(c,&stbuf))//find it
DoHTML(f,c); //send if out
}
else
{
#ifdef DEBUG
printf("Before DoDir");
#endif
// * end ='\0'; //not a index.html,so give a dirlist
DoDir(f,c);
}
}
/******************************************
else if(!strcmp(r - 4,".gif"))
{
#ifdef DEBUG
printf("Before DoGif");
#endif
DoGif(f,c);
}
else if(!strcmp(r - 5,".html"))
{
#ifdef DEBUG
printf(" Before Dohtml--last");
#endif
DoHTML(f,c);
}
else if(*c == 0)
{
strcat(c,"index.html");
if(!stat(c,&stbuf))
DoHTML(f,c);
}
*******************************************/
else
{
int e = errno;
PrintHeader(f, HTML);
alarm(TIMEOUT);
fprintf(f,"<p>File'%s'not found (error %d)</p>\n",bp,e);
alarm(0);
}
return 0;
}
void sigalrm(int signo)
{
exit(0);
}
int main(int argc,char *argv[])
{
int fd,s;
int len;
volatile int true = 1;
struct sockaddr_in ec;
struct sockaddr_in server_sockaddr;
FILE *f;
char buf[160];
char buf1[160];
size_t size = 30;
signal(SIGCHLD,SIG_IGN);// to ignore the signals of SIGCHLD & SIGPIPE
signal(SIGPIPE,SIG_IGN);
signal(SIGALRM,sigalrm);// SIGALRM handler
if(chdir("/htdocs") == -1)
{
perror("Unable to find the directory you asked...\n");
printf("Current working DIRectory: %s\n",getcwd(buf, size));
exit(1);
}
restart:
if((s = socket(AF_INET,SOCK_STREAM,0)) == -1)
{
perror("Unable to obtain network");
exit(1);
}
if((setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(void*)&true,sizeof(true))) == -1)
{
perror("socketopt failed");
exit(1);
}
bzero((struct sockaddr*) &server_sockaddr,sizeof(server_sockaddr));
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(SERVER_PORT);
server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(s, (struct sockaddr*) &server_sockaddr, sizeof(server_sockaddr)) == -1)
{
if((errno == EADDRINUSE) && (getpid()!= 1))
printf("Please do not use this command\n");
else
perror("Unable to bind socket");
exit(1);
}
if(listen(s, 8*3) == -1) //queue length 8*3,8 files per page, 3 clients
{
perror("Unable to listen");
exit(4);
goto restart; //waiting failure,ceate a socket again
}
#ifdef DEBUG
printf("\n\nServer is running......\n\n");
#endif
while(1)
{
len = sizeof(ec);
if((fd = accept(s, (void*)&ec, &len)) == -1)
{
exit(5);
close(s);
goto restart; //accept failuer,create a socket again
}
f = fdopen(fd, "a+"); //open hypertext file information
if(!f)
{
fprintf(stderr,"httpd:Unable to open https input fd,error %d\n",errno);
alarm(TIMEOUT);
close(fd);
alarm(0);
continue;
}
setbuf(f,0); //clear the buffer
alarm(TIMEOUT);
//if(!fread(buf, sizeof(char), 1500, f))
if(!fgets(buf, 150, f)) //read information to string
{
fprintf(stderr,"httpd:Error reading connection,error %d\n", errno);
fclose(f);
alarm(0);
continue;
}
#ifdef DEBUG
printf("buf = %s\n", buf);
#endif
alarm(0);
referrer[0] = '\0'; //time out, disconnect
content_length = -1;
alarm(TIMEOUT);
while(fgets(buf1,150,f) && (strlen(buf1) > 2))//socket recv data in loops
//while(fread(buf1, sizeof(char), 150, f) && (strlen(buf1) > 2))
{
alarm(TIMEOUT);
#ifdef DEBUG
printf("Got buf1 %s", buf1);
#endif
if(!strncasecmp(buf1,"Referer:",8))
{ //if the first seventh words in buf1 is"Referer",the point moved to 9th
char * c = buf1 + 8;
while(isspace (*c))
c++;
strcpy(referrer,c);
}
else if(!strncasecmp(buf1,"Referer:",9))
{
char * c = buf1 + 9;
while(isspace(*c))
c++;
strcpy(referrer,c);
}
else if(!strncasecmp(buf1,"Content-length:",15)) //if the head char is
//Content-length, c will point the 16th. char
content_length = atoi(buf + 15);//return interger length of file
}
alarm(0);
if(ferror(f))
{
fprintf(stderr, "http: Error continuing reading connection,error %d\n", errno);
fclose(f);
continue;
}
ParseReq(f, buf);//parse the instrction parameter send by browser and
// react with certain methods
alarm(TIMEOUT);
fflush(f);
fclose(f);
alarm(0);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -