#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define SERVER_IP "127.0.0.1"
#define NOFILE 256
#define MAXBUF 1024
#define MAXPATH 150
char ip[128];
char port[128];
char back[128];
char home_dir[128];
char buffer[MAXBUF + 1];
void init_deamon(const char *pname, int facility) { //set the process to wait-process
int pid;
int i;
signal(SIGTTOU, SIG_IGN);
signal(SIGTTIN, SIG_IGN);
signal(SIGTSTP, SIG_IGN);
signal(SIGHUP, SIG_IGN);
if (pid = fork())
exit(EXIT_SUCCESS);
else if (pid < 0) {
perror("socket!");
exit(EXIT_FAILURE);
}
setsid();
if (pid = fork())
exit(EXIT_SUCCESS);
else if (pid < 0) {
perror("socket!");
exit(EXIT_FAILURE);
}
for (i = 0; i < NOFILE; i++)
close(i);
open("/dev/null", O_RDONLY);
open("/dev/null", O_RDWR);
open("/dev/null", O_RDWR);
chdir("/tmp");
umask(0);
signal(SIGCHLD, SIG_IGN);
openlog(pname, LOG_PID, facility);
return;
}
void write_log(char *msg){
syslog(LOG_INFO, "%s", msg);
}
int get_arg(char *cmd) { //read the configure file
FILE *fp;
char buffer[1024];
size_t bytes_read;
char* match;
fp = fopen("/root/NetBeansProjects/LINUX-Design/test_httpd.conf", "r");
bytes_read = fread(buffer, 1, sizeof (buffer), fp);
fclose(fp);
if (bytes_read == 0 || bytes_read == sizeof (buffer))
return 0;
buffer[bytes_read] = '\0';
if (!strncmp(cmd, "home_dir", 8)) {
match = strstr(buffer, "home_dir=");
if (match == NULL)
return 0;
bytes_read = sscanf(match, "home_dir=%s", home_dir);
return bytes_read;
} else if (!strncmp(cmd, "port", 4)) {
match = strstr(buffer, "port=");
if (match == NULL)
return 0;
bytes_read = sscanf(match, "port=%s", port);
return bytes_read;
} else if (!strncmp(cmd, "ip", 2)) {
match = strstr(buffer, "ip=");
if (match == NULL)
return 0;
bytes_read = sscanf(match, "ip=%s", ip);
return bytes_read;
} else if (!strncmp(cmd, "back", 4)) {
match = strstr(buffer, "back=");
if (match == NULL)
return 0;
bytes_read = sscanf(match, "back=%s", back);
return bytes_read;
} else
return;
}
int make_server_socket() {
struct sockaddr_in addr;
int sock_fd, addrlen;
if (get_arg("home_dir") == 0) {
sprintf(home_dir, "%s", "/tmp");
}
if (get_arg("ip") == 0) {
get_addr("eth0");
}
if (get_arg("port") == 0) {
sprintf(port, "%s", "80");
}
if (get_arg("port") == 0) {
sprintf(back, "%s", "5");
}
if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
write_log("socket!");
exit(EXIT_FAILURE);
}
addrlen = 1;
setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &addrlen, sizeof (addrlen));
addr.sin_family = AF_INET;
addr.sin_port = htons(atoi(port));
addr.sin_addr.s_addr = inet_addr(ip);
addrlen = sizeof (struct sockaddr_in);
if (bind(sock_fd, &addr, sizeof (addr)) < 0) {
write_log("bind!");
exit(EXIT_FAILURE);
}
if (listen(sock_fd, 5) < 0) {
write_log("listen!");
exit(EXIT_FAILURE);
}
return sock_fd;
}
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;
}
void response(FILE *client_sock, char *Path) {
struct dirent *dirent;
struct stat info;
char Filename[MAXPATH];
DIR *dir;
int fd, len, ret;
char *p, *realPath, *realFilename, *nport;
/* 获得实际工作目录或文件 */
len = strlen(home_dir) + strlen(Path) + 1;
realPath = malloc(len + 1);
bzero(realPath, len + 1);
sprintf(realPath, "%s/%s", home_dir, Path);
/* 获得实际工作端口 */
len = strlen(port) + 1;
nport = malloc(len + 1);
bzero(nport, len + 1);
sprintf(nport, ":%s", port);
/* 获得实际工作目录或文件的信息以判断是文件还是目录 */
if (stat(realPath, &info)) {
fprintf(client_sock,
"HTTP/1.1 200 OK\r\nServer: DAS by ZhouLifa\r\nConnection: close\r\n\r\n
"Linux HTTP SERVER
"
Path, strerror(errno));
goto out;
}
/* 处理浏览文件请求,即下载文件 */
if (S_ISREG(info.st_mode)) {
fd = open(realPath, O_RDONLY);
len = lseek(fd, 0, SEEK_END);
p = (char *) malloc(len + 1);
bzero(p, len + 1);
lseek(fd, 0, SEEK_SET);
ret = read(fd, p, len);
close(fd);
fprintf(client_sock,
"HTTP/1.1 200 OK\r\nServer: linux HTTP SERVER\r\nConnection: keep-alive\r\nContent-type: application/*\r\nContent-Length:%d\r\n\r\n",
len);
fwrite(p, len, 1, client_sock);
free(p);
} else if (S_ISDIR(info.st_mode)) {
/* 处理浏览目录请求 */
dir = opendir(realPath);
fprintf(client_sock,
"HTTP/1.1 200 OK\r\nServer: linux HTTP SERVER\r\nConnection: close\r\n\r\n
"Linux Http Server File
"
name | size | modify time |
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(client_sock, "
len = strlen(home_dir) + strlen(Filename) + 1;
realFilename = malloc(len + 1);
bzero(realFilename, len + 1);
sprintf(realFilename, "%s/%s", home_dir, Filename);
if (stat(realFilename, &info) == 0) {
if (strcmp(dirent->d_name, "..") == 0)
fprintf(client_sock,
"
ip, atoi(port) == 80 ? "" : nport,
dir_up(Path));
else
fprintf(client_sock,
"
ip, atoi(port) == 80 ? "" : nport, Filename,
dirent->d_name);
if (S_ISDIR(info.st_mode))
fprintf(client_sock, "
else if (S_ISREG(info.st_mode))
fprintf(client_sock, "
else if (S_ISLNK(info.st_mode))
fprintf(client_sock, "
else if (S_ISCHR(info.st_mode))
fprintf(client_sock, "
else if (S_ISBLK(info.st_mode))
fprintf(client_sock, "
else if (S_ISFIFO(info.st_mode))
fprintf(client_sock, "
else if (S_ISSOCK(info.st_mode))
fprintf(client_sock, "
else
fprintf(client_sock, "
fprintf(client_sock, "
}
fprintf(client_sock, "
free(realFilename);
}
fprintf(client_sock, "