www.pudn.com > Demo C.rar > VxHttp.c


/*  
 * quick-and-dirty HTTP server which allows a remote web browser 
 * to interface with the target machine. 
 */ 
 
#include "vxWorks.h" 
#include "sys/types.h" 
#include "ioLib.h" 
#include "ifLib.h" 
#include "fioLib.h" 
#include "stdio.h" 
#include "unistd.h" 
#include "string.h" 
#include "usrLib.h" 
#include "errnoLib.h" 
#include "hostLib.h" 
#include "sockLib.h" 
#include "socket.h" 
#include "inetLib.h" 
#include "in.h" 
#include "selectLib.h" 
#include "taskLib.h" 
#include "ctype.h" 
#include "dirent.h" 
#include "sys/stat.h" 
#include "errnoLib.h" 
#include "fcntl.h" 
#include "unistd.h" 
#include "fioLib.h" 
 
/*********** kludge delay to make this work! ***************/ 
int		kludge_delay = 0; 
/*********** kludge delay to make this work! ****************/ 
 
int vhttpVerbose = 1; 
 
#define HTTP_PORT		80 
#define DEBUG			1		/* XXX */ 
#define MAX_SESSIONS	12		/* 12 concurrent HTTP sessions */ 
 
WIND_TCB *vhttp_tasks [MAX_SESSIONS]; 
WIND_TCB *vhttpd_task = 0; 
 
char	MyIPAddr[32]; 
 
char	*getMyIpAddr() 
{ 
ifAddrGet( "cs0",MyIPAddr ); 
return MyIPAddr; 
} 
 
int vt1(); 
int vt2(); 
int vt3(); 
 
/* 
 * customizable menu User interface 
 */ 
struct vtMenu { 
    char * menu_desc; 
    int (* menu_func)(); 
}; 
 
#define MAX_CMDS 3	/* XXX this must match the struct below */ 
 
/* list of available commands and callback functions */ 
struct vtMenu vtCmds[MAX_CMDS] = { 
	{ "1. Stuff",  vt1 }, 
	{ "2. More Stuff", vt2 }, 
	{ "3. More and More Stuff", vt3 }, 
}; 
 
 
int vt1() 
{ 
	printf("Command Handler: vt1, Stuff\n"); 
	return OK; 
} 
 
int vt2() 
{ 
	printf("Command Handler: vt2, More Stuff\n"); 
	return OK; 
} 
 
int vt3() 
{ 
	printf("Command Handler: vt3, More and More Stuff\n"); 
	return OK; 
} 
 
 
#ifdef DEBUG 
static void 
errorMsg(char *msg) 
{ 
  printf("ERROR: %s, errno 0x%x\n", msg, errnoGet()); 
} 
 
static void 
infoMsg(char *msg) 
{ 
  printf("INFO: %s\n", msg); 
} 
#else 
#define errorMsg(msg)	; 
#define infoMsg(msg)	; 
#endif 
 
int 
vhttpReadInputLine(int sock, char *buffer) 
{ 
  int num; 
  int i; 
   
  if (ioctl(sock, FIONREAD, &num) < 0){ 
    errorMsg("vhttpReadInputLine: ioctl FIONREAD error"); 
    return -1; 
  } 
  if (num < 1) return -1; 
  for (i=0;;) { 
    char ch; 
    int count; 
     
    count = read(sock, &ch, 1); 
    if (count < 1) { 
      errorMsg("vhttpReadInputLine: read error"); 
      return -2; 
    } 
    if (ch == (char)0xd) {	/* carriage return */ 
      read(sock, &ch, 1);	/* eat linefeed */ 
      if (ch != (char)0xa) { 
	  errorMsg("vhttpReadInputLine: LF expected but got someting else"); 
	  return -2; 
      } 
    break; 
    } 
  buffer[i++] = ch; 
  } 
buffer[i] = '\0'; 
return(i); 
} 
 
 
void 
vhttpSendErr(int sock, int code, char *msg) 
{ 
  char buf[128]; 
   
  sprintf(buf, "%d %s\n", code, msg); 
#ifdef DEBUG 
  printf(buf); 
#endif 
  write(sock, buf, strlen(buf)); 
} 
 
int 
vhttpWriteSock(int sock, char *msg) 
{ 
int	result =  write (sock, msg, strlen(msg)); 
 
/*********** kludge delay to make this work! ***************/ 
	if( kludge_delay ) taskDelay( kludge_delay ); 
/*********** kludge delay to make this work! ****************/ 
 
  return result; 
} 
 
void 
vhttpSendText(int sock, char *URL) 
{ 
  int i; 
  struct vtMenu *mp; 
  char buf[128]; 
  char my_addr[20]; 
  vhttpWriteSock(sock, "HTTP/1.0 200 OK\nMIME-Version: 1.0\nContent-Type: "); 
  vhttpWriteSock(sock, "text/html\n\n"); 
  vhttpWriteSock(sock, "Bigger Text File"); 
  vhttpWriteSock(sock, "\n"); 
  vhttpWriteSock(sock, "
\n

"); vhttpWriteSock(sock, "URL: "); vhttpWriteSock(sock, URL ); vhttpWriteSock(sock, "

"); vhttpWriteSock(sock, "


"); vhttpWriteSock(sock, "

"); vhttpWriteSock(sock, "
"); vhttpWriteSock(sock, "\n"); } void vhttpSendMenu(int sock) { int i; struct vtMenu *mp; char buf[128]; char my_addr[20]; memset(my_addr,0,sizeof(my_addr)); sprintf(my_addr,"

My IP is: %s

",getMyIpAddr()); vhttpWriteSock(sock, "HTTP/1.0 200 OK\nMIME-Version: 1.0\nContent-Type: "); vhttpWriteSock(sock, "text/html\n\n"); vhttpWriteSock(sock, "Welcome to MyHacks, Inc."); vhttpWriteSock(sock, "\n"); vhttpWriteSock(sock, "

Welcome To MyHacks, Inc.

\n"); vhttpWriteSock(sock, my_addr); vhttpWriteSock(sock, "


\n"); } int vhttpSendHTML(int sock, char *HTML) { int inFd; int s=0; inFd = open (HTML, O_RDONLY, 0); if (inFd < OK) { errorMsg("can't open HTML file"); return (ERROR); } vhttpWriteSock(sock, "HTTP/1.0 200 OK\nMIME-Version: 1.0\nContent-Type: "); vhttpWriteSock(sock, "text/html\n\n"); vhttpWriteSock(sock, "SENDING HTML\n\n"); return (s); } int vhttpSendGIF(int sock, char *GIF) { int inFd; int s=0; inFd = open (GIF, O_RDONLY, 0); if (inFd < OK) { errorMsg("can't open GIF file"); return (ERROR); } vhttpWriteSock(sock, "HTTP/1.0 200 OK\nMIME-Version: 1.0\nContent-Type: "); vhttpWriteSock(sock, "image/gif\n\n"); vhttpWriteSock(sock, "SENDING GIF\n\n"); return (s); } int vhttpSendJPEG(int sock, char *JPEG) { int inFd; int s=0; inFd = open (JPEG, O_RDONLY, 0); if (inFd < OK) { errorMsg("can't open JPEG file"); return (ERROR); } vhttpWriteSock(sock, "HTTP/1.0 200 OK\nMIME-Version: 1.0\nContent-Type: "); vhttpWriteSock(sock, "image/jpeg\n\n"); vhttpWriteSock(sock, "SENDING JPG\n\n"); return (s); } int vhttpProcessURL(int sock, char *URL) { int num; int result; char *suffix; #ifdef DEBUG printf("URL requested <%s>\n", URL); #endif if(URL[1]==' ') URL[1]=0; if (strcmp(URL, "/" ) == 0) vhttpSendMenu(sock); else { suffix = strrchr(URL, '.'); #ifdef DEBUG printf("URL requested Suffix=%s\n", suffix); #endif if (suffix != 0) { if (strcmp(suffix,".html") == 0) vhttpSendHTML(sock,++URL); else if (strcmp(suffix,".gif") == 0) vhttpSendGIF(sock,++URL); else if (strcmp(suffix,".jpeg") == 0) vhttpSendJPEG(sock,++URL); else if (strcmp(suffix,".text") == 0) vhttpSendText(sock,++URL); else { vhttpSendMenu(sock); vhttpSendErr(sock, 666, "Unknown URL"); vhttpSendErr(sock, 666, URL); } } else { URL[0] = ' '; /* wipe out leading slash char */ num = atoi(URL); if (num >= 0 && num < MAX_CMDS) { #ifdef DEBUG printf("URL requested dispatch to command handler: %d\n", num ); #endif vhttpSendMenu(sock); result = (*vtCmds[num].menu_func)(); if (result == OK) vhttpSendErr(sock, 205, "Command success"); else vhttpSendErr(sock, 905, "Command Failed"); } else { vhttpSendErr(sock, 505, "Invalid menu item URL"); return ERROR; } } } return OK; } int vhttpProcess(int sock, struct sockaddr_in *sinptr) { fd_set read_fdset; fd_set write_fdset; fd_set except_fdset; int finishedHeader=0; char buffer[1024]; char method[20]; char URL[200]; char proto[20]; char *p1,*p2; fprintf(stderr,"\nVHTTP Process "); for (;;) { FD_SET(sock, &read_fdset); FD_SET(sock, &write_fdset); FD_SET(sock, &except_fdset); if (select(64, &read_fdset, &write_fdset, &except_fdset, 0) < 0) continue; if (FD_ISSET(sock, &read_fdset)) { int result; result = vhttpReadInputLine(sock, buffer); memset(method,0,sizeof(method)); memset(URL,0,sizeof(URL)); strncpy(method,buffer,3); p1 = URL; p2 = &buffer[4]; while( !isspace(*p2) ) *p1++ = *p2++; /*strncpy(URL,&buffer[4],strlen(buffer)-4);*/ fprintf(stderr,"\nVHTTP: rdInpLine[%u]=%s ",result,buffer ); fprintf(stderr,"\nVHTTP: method=%s ",method ); fprintf(stderr,"\nVHTTP: URL=%s ",URL ); fprintf(stderr,"\n"); if (result < 0) return -1; if (result == 0) { finishedHeader=1; return 0; } if (!finishedHeader) { if (strcmp(method, "GET") != 0 && strcmp(method, "PUT") != 0) { vhttpSendErr(sock, 501, "Invalid Method. Expecting GET or PUT."); close(sock); return -1; } if (vhttpProcessURL(sock, URL) != OK) { vhttpSendErr(sock, 404, "Invalid URL"); close(sock); return -1; } close(sock); finishedHeader=1; return 0; } } else if (FD_ISSET(sock, &write_fdset)) { ; } else if (FD_ISSET(sock, &except_fdset)) { errorMsg("exception fd set"); } #if 0 taskDelay(2 * 60); #endif } } int vhttpMainLoop(int sock, struct sockaddr_in *sinptr) { int client; char name[25]; static int procNum = 1; int i; int size; fprintf(stderr,"\nVHTTP Main Loop "); for (;;) { WIND_TCB *tcb; size = sizeof(*sinptr); client = accept(sock, (struct sockaddr *)sinptr, &size); if (client < 0) { errorMsg("accept"); return -1; } infoMsg("vhttp: accepted a new client\n"); sprintf(name, "vhttp%d", procNum++); tcb = taskSpawn(name, 101, 0, 1024 * 4, vhttpProcess, client, sinptr, 0, 0, 0, 0, 0, 0, 0, 0); tcb->spare4 = client; for (i = 0; i < MAX_SESSIONS; i++) { if (vhttp_tasks[i] == 0) break; } if (i < MAX_SESSIONS) vhttp_tasks[i] = tcb; else { vhttpSendErr(sock, 501, "Too many sessions"); close(client); return -1; } } return OK; } int vhttpDelete(WIND_TCB *tcb) { int i; if (tcb == vhttpd_task) close(tcb->spare4); /* delete server socket */ for (i = 0; i < MAX_SESSIONS; i++) { if (tcb == vhttp_tasks[i]) { close(tcb->spare4); vhttp_tasks[i] = 0; } } } int vxhttp() { int sock; struct sockaddr_in sin; struct sockaddr_in *sinptr = &sin; int true = 1; WIND_TCB *tcb; int i; sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { errorMsg("socket"); return -1; } if((setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&true, sizeof(true))) == -1) { errorMsg("setsockopt"); return -1; } bzero(sinptr, sizeof(*sinptr)); sinptr->sin_family = AF_INET; sinptr->sin_port = htons(HTTP_PORT); sinptr->sin_addr.s_addr = htonl(INADDR_ANY); if (bind(sock, (struct sockaddr *) sinptr, sizeof(*sinptr)) < 0) { errorMsg("bind"); return -1; } if (listen (sock, 5) < 0) { errorMsg("listen"); return -1; } for (i = 0; i < MAX_SESSIONS; i++) vhttp_tasks[i] = 0; fprintf(stderr,"\nSpawn Main VHTTP"); tcb = taskSpawn("vHttpD", 100, 0, 2048, vhttpMainLoop, sock, sinptr, 0, 0, 0, 0, 0, 0, 0, 0); tcb->spare4 = sock; vhttpd_task = tcb; taskDeleteHookAdd(vhttpDelete); return OK; }