first commit
This commit is contained in:
8
CS4210/Project 3/common/CVS/Entries
Normal file
8
CS4210/Project 3/common/CVS/Entries
Normal file
@@ -0,0 +1,8 @@
|
||||
D/config_parser////
|
||||
D/http////
|
||||
D/message////
|
||||
D/networking////
|
||||
D/shared_memory////
|
||||
D/strtok_r////
|
||||
D/thread_pool////
|
||||
/defs.h/1.5/Wed Apr 19 03:53:59 2006//
|
||||
8
CS4210/Project 3/common/CVS/Entries.Extra
Normal file
8
CS4210/Project 3/common/CVS/Entries.Extra
Normal file
@@ -0,0 +1,8 @@
|
||||
D/config_parser///////
|
||||
D/http///////
|
||||
D/message///////
|
||||
D/networking///////
|
||||
D/shared_memory///////
|
||||
D/strtok_r///////
|
||||
D/thread_pool///////
|
||||
/defs.h////*///
|
||||
8
CS4210/Project 3/common/CVS/Entries.Extra.Old
Normal file
8
CS4210/Project 3/common/CVS/Entries.Extra.Old
Normal file
@@ -0,0 +1,8 @@
|
||||
D/config_parser///////
|
||||
D/http///////
|
||||
D/message///////
|
||||
D/networking///////
|
||||
D/shared_memory///////
|
||||
D/strtok_r///////
|
||||
D/thread_pool///////
|
||||
/defs.h////*///
|
||||
8
CS4210/Project 3/common/CVS/Entries.Old
Normal file
8
CS4210/Project 3/common/CVS/Entries.Old
Normal file
@@ -0,0 +1,8 @@
|
||||
D/config_parser////
|
||||
D/http////
|
||||
D/message////
|
||||
D/networking////
|
||||
D/shared_memory////
|
||||
D/strtok_r////
|
||||
D/thread_pool////
|
||||
/defs.h/1.3/Sun Apr 2 10:07:02 2006//
|
||||
1
CS4210/Project 3/common/CVS/Repository
Normal file
1
CS4210/Project 3/common/CVS/Repository
Normal file
@@ -0,0 +1 @@
|
||||
CS4210/Project 3/common
|
||||
1
CS4210/Project 3/common/CVS/Root
Normal file
1
CS4210/Project 3/common/CVS/Root
Normal file
@@ -0,0 +1 @@
|
||||
:ext:asskoala@192.168.0.3:/usr/_CVS
|
||||
3
CS4210/Project 3/common/config_parser/CVS/Entries
Normal file
3
CS4210/Project 3/common/config_parser/CVS/Entries
Normal file
@@ -0,0 +1,3 @@
|
||||
/parser.c/1.3/Sun Apr 2 10:06:57 2006//
|
||||
/parser.h/1.3/Sun Apr 2 10:06:57 2006//
|
||||
D
|
||||
2
CS4210/Project 3/common/config_parser/CVS/Entries.Extra
Normal file
2
CS4210/Project 3/common/config_parser/CVS/Entries.Extra
Normal file
@@ -0,0 +1,2 @@
|
||||
/parser.c////*///
|
||||
/parser.h////*///
|
||||
@@ -0,0 +1,2 @@
|
||||
/parser.c////*///
|
||||
/parser.h////*///
|
||||
3
CS4210/Project 3/common/config_parser/CVS/Entries.Old
Normal file
3
CS4210/Project 3/common/config_parser/CVS/Entries.Old
Normal file
@@ -0,0 +1,3 @@
|
||||
/parser.c/0/dummy timestamp//
|
||||
/parser.h/0/dummy timestamp//
|
||||
D
|
||||
1
CS4210/Project 3/common/config_parser/CVS/Repository
Normal file
1
CS4210/Project 3/common/config_parser/CVS/Repository
Normal file
@@ -0,0 +1 @@
|
||||
CS4210/Project 3/common/config_parser
|
||||
1
CS4210/Project 3/common/config_parser/CVS/Root
Normal file
1
CS4210/Project 3/common/config_parser/CVS/Root
Normal file
@@ -0,0 +1 @@
|
||||
:ext:asskoala@192.168.0.3:/usr/_CVS
|
||||
85
CS4210/Project 3/common/config_parser/parser.c
Normal file
85
CS4210/Project 3/common/config_parser/parser.c
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "parser.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static char* getNextLine(char arr[160], FILE* stream) {
|
||||
while (fgets(arr, 160, stream)) {
|
||||
if (arr[0] == '#' || !isalnum(arr[0])) {
|
||||
continue;
|
||||
} else {
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Load fileName and return a FILE*
|
||||
*/
|
||||
ConfigFile* loadFile(char* fileName) {
|
||||
ConfigFile* newConfig = NULL;
|
||||
|
||||
newConfig = malloc(sizeof(ConfigFile));
|
||||
if (!newConfig) {
|
||||
printf("Memory Allocation Failed in _FILE_ line: _LINE_\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
newConfig->file = fopen(fileName, "r");
|
||||
|
||||
if (!newConfig->file) {
|
||||
free(newConfig);
|
||||
printf("Failed to Open File in _FILE_: _LINE_\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return newConfig;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void releaseConfig(ConfigFile** configFile) {
|
||||
|
||||
if (!configFile) {
|
||||
return;
|
||||
}
|
||||
if ((*configFile)->file) {
|
||||
fclose((*configFile)->file);
|
||||
}
|
||||
free(*configFile);
|
||||
*configFile = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int nextSet(ConfigFile* config) {
|
||||
char temp[160];
|
||||
char* pc;
|
||||
int i;
|
||||
|
||||
if (!getNextLine(temp, config->file)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pc = strtok(temp,":");
|
||||
|
||||
strncpy(config->currentParamter, pc, 80);
|
||||
|
||||
pc = strtok(NULL,":");
|
||||
|
||||
for (i=0; pc[i] != '\0'; i++) {
|
||||
if (isspace(pc[i])) {
|
||||
pc[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
strncpy(config->currentValue, pc, 80);
|
||||
|
||||
return 1;
|
||||
}
|
||||
22
CS4210/Project 3/common/config_parser/parser.h
Normal file
22
CS4210/Project 3/common/config_parser/parser.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef _PARSER_H_
|
||||
#define _PARSER_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct SCONFIGFILE {
|
||||
char currentParamter[80];
|
||||
char currentValue[80];
|
||||
FILE* file;
|
||||
} ConfigFile;
|
||||
|
||||
/*
|
||||
* Load a file
|
||||
*/
|
||||
ConfigFile* loadFile(char* fileName);
|
||||
void releaseConfig(ConfigFile**);
|
||||
|
||||
int nextSet(ConfigFile*);
|
||||
|
||||
#endif
|
||||
|
||||
20
CS4210/Project 3/common/defs.h
Normal file
20
CS4210/Project 3/common/defs.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef _DEFS_H_
|
||||
#define _DEFS_H_
|
||||
|
||||
#define _VERBOSE_ 0 // Print out generally useless stuff
|
||||
#define _LOG_ 0 // Print out loging output, turn off for speed
|
||||
#define VPRINTF(x) if(_VERBOSE_) printf x;
|
||||
#define BZERO(x,z) memset(x,0,z)
|
||||
|
||||
#define _THREAD_POOL_ //Whether to spwan new threads for each connection
|
||||
//or use pooling
|
||||
|
||||
#define LOCAL_GET "LOCAL_GET"
|
||||
|
||||
#define DieWithError(msg) { \
|
||||
fprintf(stderr, "%s: PwnT! Error on line %d.\n", (msg), __LINE__); \
|
||||
perror(msg); \
|
||||
exit(EXIT_FAILURE);}
|
||||
|
||||
#endif
|
||||
|
||||
3
CS4210/Project 3/common/http/CVS/Entries
Normal file
3
CS4210/Project 3/common/http/CVS/Entries
Normal file
@@ -0,0 +1,3 @@
|
||||
/http.c/1.3/Sun Apr 2 10:06:57 2006//
|
||||
/http.h/1.3/Sun Apr 2 10:06:57 2006//
|
||||
D
|
||||
2
CS4210/Project 3/common/http/CVS/Entries.Extra
Normal file
2
CS4210/Project 3/common/http/CVS/Entries.Extra
Normal file
@@ -0,0 +1,2 @@
|
||||
/http.c////*///
|
||||
/http.h////*///
|
||||
2
CS4210/Project 3/common/http/CVS/Entries.Extra.Old
Normal file
2
CS4210/Project 3/common/http/CVS/Entries.Extra.Old
Normal file
@@ -0,0 +1,2 @@
|
||||
/http.c////*///
|
||||
/http.h////*///
|
||||
3
CS4210/Project 3/common/http/CVS/Entries.Old
Normal file
3
CS4210/Project 3/common/http/CVS/Entries.Old
Normal file
@@ -0,0 +1,3 @@
|
||||
/http.c/0/dummy timestamp//
|
||||
/http.h/0/dummy timestamp//
|
||||
D
|
||||
1
CS4210/Project 3/common/http/CVS/Repository
Normal file
1
CS4210/Project 3/common/http/CVS/Repository
Normal file
@@ -0,0 +1 @@
|
||||
CS4210/Project 3/common/http
|
||||
1
CS4210/Project 3/common/http/CVS/Root
Normal file
1
CS4210/Project 3/common/http/CVS/Root
Normal file
@@ -0,0 +1 @@
|
||||
:ext:asskoala@192.168.0.3:/usr/_CVS
|
||||
419
CS4210/Project 3/common/http/http.c
Normal file
419
CS4210/Project 3/common/http/http.c
Normal file
@@ -0,0 +1,419 @@
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include "http.h"
|
||||
#include "../defs.h"
|
||||
|
||||
#define SERVER_NAME "ubermicro_httpd"
|
||||
#define SERVER_URL "http://www.puyan.org"
|
||||
#define PROTOCOL "HTTP/1.1"
|
||||
#define RFC1123FMT "%a, %d %b %Y %H:%M:%S GMT"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define S_ISDIR(a) (a & S_IFDIR)
|
||||
char lower(const char a);
|
||||
int strcasecmp(const char *s1, const char *s2);
|
||||
#endif
|
||||
|
||||
static void file_details( char* dir, char* name , FILE *socket_file);
|
||||
static void send_error( int status, char* title, char* extra_header, char* text, FILE *socket_file );
|
||||
static void send_headers( int status, char* title, char* extra_header, char* mime_type, off_t length, time_t mod, FILE *socket_file );
|
||||
static char* get_mime_type( char* name );
|
||||
static void strdecode( char* to, char* from );
|
||||
static int hexit( char c );
|
||||
static void strencode( char* to, size_t tosize, const char* from );
|
||||
|
||||
int parse_request(char *request, http_request *package) {
|
||||
if ( sscanf(request, "%[^ ] %[^ ] %[^ ]", package->method, package->path, package->protocol ) != 3 ) {
|
||||
return EXIT_FAILURE;
|
||||
} else {
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
return EXIT_FAILURE; // Never Reached
|
||||
}
|
||||
|
||||
void http_proto(int socket, char *request) {
|
||||
char idx[2000], location[2000];
|
||||
char *method, *path, *protocol;
|
||||
char* file;
|
||||
size_t len;
|
||||
int ich;
|
||||
struct stat sb;
|
||||
FILE* fp;
|
||||
FILE* socket_file;
|
||||
struct dirent **dl;
|
||||
int i, n;
|
||||
char *brkt;
|
||||
char *true_request;
|
||||
http_request request_package;
|
||||
|
||||
VPRINTF(("\n\nStart http proc\n"));
|
||||
|
||||
VPRINTF(("Full Request:\n%s\n", request));
|
||||
|
||||
true_request=strtok_r(request,"\r", &brkt);
|
||||
|
||||
VPRINTF(("Request size: %d\n", strlen(request)));
|
||||
VPRINTF(("Small Request: \n%s\n", true_request));
|
||||
VPRINTF(("1 error on line %d\n", __LINE__));
|
||||
|
||||
socket_file = fdopen(socket, "w");
|
||||
fflush( socket_file ); //FIXME: May not be necessary, nothing written yet
|
||||
|
||||
if(strlen(request) >= BUFFERSIZE) {
|
||||
send_error( 403, "Bad Request", (char*) 0, "No request found." , socket_file );
|
||||
goto complete;
|
||||
}
|
||||
|
||||
if (EXIT_FAILURE == parse_request(request, &request_package)) {
|
||||
send_error( 400, "Bad Request", (char*) 0, "Can't parse request." , socket_file );
|
||||
goto complete;
|
||||
} else {
|
||||
method = request_package.method;
|
||||
path = request_package.path;
|
||||
protocol = request_package.protocol;
|
||||
}
|
||||
|
||||
VPRINTF(("Method: %s\n", method));
|
||||
VPRINTF(("Path: %s\n", path));
|
||||
VPRINTF(("Protocol: %s\n", protocol));
|
||||
VPRINTF(("2 error on line %d\n", __LINE__));
|
||||
|
||||
if ( strcasecmp( method, "get" ) != 0 ) {
|
||||
send_error( 501, "Not Implemented", (char*) 0, "That method is not implemented." , socket_file );
|
||||
goto complete;
|
||||
}
|
||||
|
||||
VPRINTF(("3 error on line %d\n", __LINE__));
|
||||
|
||||
if ( path[0] != '/' ) {
|
||||
send_error( 400, "Bad Request", (char*) 0, "Bad filename." , socket_file );
|
||||
goto complete;
|
||||
}
|
||||
|
||||
file = &(path[1]);
|
||||
strdecode( file, file );
|
||||
|
||||
if ( file[0] == '\0' ) {
|
||||
file = "./";
|
||||
}
|
||||
|
||||
len = strlen( file );
|
||||
|
||||
VPRINTF(("4 error on line %d\n", __LINE__));
|
||||
|
||||
if ( file[0] == '/'
|
||||
|| strcmp( file, ".." ) == 0
|
||||
|| strncmp( file, "../", 3 ) == 0
|
||||
|| strstr( file, "/../" ) != (char*) 0
|
||||
|| strcmp( &(file[len-3]), "/.." ) == 0 )
|
||||
{
|
||||
send_error( 400, "Bad Request", (char*) 0, "Illegal filename." , socket_file );
|
||||
goto complete;
|
||||
}
|
||||
|
||||
if ( stat( file, &sb ) < 0 ) {
|
||||
send_error( 404, "Not Found", (char*) 0, "File not found." , socket_file );
|
||||
goto complete;
|
||||
}
|
||||
|
||||
if ( S_ISDIR( sb.st_mode ) ) {
|
||||
if ( file[len-1] != '/' ) {
|
||||
snprintf(location, sizeof(location), "Location: %s/", path );
|
||||
send_error( 302, "Found", location, "Directories must end with a slash." , socket_file );
|
||||
goto complete;
|
||||
}
|
||||
|
||||
snprintf( idx, sizeof(idx), "%sindex.html", file );
|
||||
|
||||
if ( stat( idx, &sb ) >= 0 )
|
||||
{
|
||||
file = idx;
|
||||
goto do_file; //asshole
|
||||
}
|
||||
|
||||
/* IMPORTANT */
|
||||
send_headers( 200, "Ok", (char*) 0, "text/html", -1, sb.st_mtime , socket_file );
|
||||
|
||||
fprintf(socket_file,
|
||||
"<html><head><title>Index of %s</title></head>\n<body bgcolor=\"lightblue\"><h4>Index of %s</h4>\n<pre>\n",
|
||||
file, file
|
||||
);
|
||||
|
||||
n = scandir( file, &dl, NULL, alphasort ); /* IMPORTANT */
|
||||
|
||||
if ( n < 0 ) {
|
||||
perror( "scandir" );
|
||||
} else {
|
||||
for ( i = 0; i < n; ++i ) {
|
||||
/* IMPORTANT */
|
||||
file_details( file, dl[i]->d_name, socket_file );
|
||||
free(dl[i]);
|
||||
/* the guy that wrote this was a n00b */
|
||||
}
|
||||
free(dl); /* Must kill this guy */
|
||||
}
|
||||
|
||||
|
||||
fprintf(socket_file,
|
||||
"</pre>\n<hr>\n<address><a href=\"%s\">%s</a></address>\n</body></html>\n",
|
||||
SERVER_URL, SERVER_NAME
|
||||
);
|
||||
} else {
|
||||
do_file:
|
||||
fp = fopen( file, "r" );
|
||||
|
||||
if ( fp == (FILE*) 0 ) {
|
||||
send_error( 403, "Forbidden", (char*) 0, "File is protected.", socket_file );
|
||||
goto complete;
|
||||
}
|
||||
|
||||
/* IMPORTANT */
|
||||
send_headers( 200, "Ok", (char*) 0, get_mime_type( file ), sb.st_size, sb.st_mtime , socket_file );
|
||||
|
||||
while (fp && ( ich = getc( fp ) ) != EOF ) {
|
||||
fprintf(socket_file,"%c", ich );
|
||||
}
|
||||
|
||||
if (fp) fclose(fp);
|
||||
}
|
||||
|
||||
complete: //because this guy wrote terrible code, goto is necessary
|
||||
|
||||
fflush( socket_file );
|
||||
|
||||
fclose(socket_file);
|
||||
}
|
||||
|
||||
|
||||
static void file_details( char* dir, char* name, FILE *socket_file )
|
||||
{
|
||||
static char encoded_name[1000];
|
||||
static char path[2000];
|
||||
struct stat sb;
|
||||
char timestr[16];
|
||||
|
||||
strencode( encoded_name, sizeof(encoded_name), name );
|
||||
snprintf( path, sizeof(path), "%s/%s", dir, name );
|
||||
|
||||
#ifdef _WIN32
|
||||
if ( stat( path, &sb ) < 0 ) {
|
||||
#else
|
||||
if ( lstat( path, &sb ) < 0 ) {
|
||||
#endif
|
||||
fprintf(socket_file, "<a href=\"%s\">%-32.32s</a> ???\n", encoded_name, name );
|
||||
} else {
|
||||
strftime(timestr, sizeof(timestr),
|
||||
"%d%b%Y %H:%M", localtime( &sb.st_mtime )
|
||||
);
|
||||
fprintf(socket_file,
|
||||
"<a href=\"%s\">%-32.32s</a> %15s %14lld\n", encoded_name,
|
||||
name, timestr, (int64_t) sb.st_size
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void send_error( int status, char* title, char* extra_header, char* text, FILE *socket_file )
|
||||
{
|
||||
send_headers( status, title, extra_header, "text/html", -1, -1, socket_file );
|
||||
|
||||
fprintf(socket_file,
|
||||
"<html><head><title>%d %s</title></head>\n<body bgcolor=\"#cc9999\"><h4>%d %s</h4>\n",
|
||||
status, title, status, title
|
||||
);
|
||||
|
||||
fprintf(socket_file, "%s\n", text );
|
||||
fprintf(socket_file, "<hr>\n<address><a href=\"%s\">%s</a></address>\n", SERVER_URL, SERVER_NAME);
|
||||
//fprintf(socket_file, "<img src=\"/pwner.jpg\">\n");
|
||||
fprintf(socket_file, "</body></html>\n");
|
||||
|
||||
fflush( socket_file ); //flush socket
|
||||
}
|
||||
|
||||
|
||||
static void send_headers( int status, char* title, char* extra_header, char* mime_type, off_t length, time_t mod , FILE *socket_file)
|
||||
{
|
||||
time_t now;
|
||||
char timebuf[100];
|
||||
|
||||
fprintf(socket_file, "%s %d %s\015\012", PROTOCOL, status, title );
|
||||
fprintf(socket_file, "Server: %s\015\012", SERVER_NAME );
|
||||
|
||||
now = time( (time_t*) 0 );
|
||||
|
||||
strftime( timebuf, sizeof(timebuf), RFC1123FMT, gmtime( &now ) );
|
||||
fprintf(socket_file, "Date: %s\015\012", timebuf );
|
||||
|
||||
if ( extra_header != (char*) 0 ) {
|
||||
fprintf(socket_file, "%s\015\012", extra_header );
|
||||
}
|
||||
if ( mime_type != (char*) 0 ) {
|
||||
fprintf(socket_file, "Content-Type: %s\015\012", mime_type );
|
||||
}
|
||||
if ( length >= 0 ) {
|
||||
fprintf(socket_file, "Content-Length: %lld\015\012", (int64_t) length );
|
||||
}
|
||||
if ( mod != (time_t) -1 )
|
||||
{
|
||||
strftime( timebuf, sizeof(timebuf), RFC1123FMT, gmtime( &mod ) );
|
||||
fprintf(socket_file, "Last-Modified: %s\015\012", timebuf );
|
||||
}
|
||||
fprintf(socket_file, "Connection: close\015\012" );
|
||||
fprintf(socket_file, "\015\012" );
|
||||
}
|
||||
|
||||
|
||||
static char* get_mime_type( char* name )
|
||||
{
|
||||
char* dot;
|
||||
|
||||
dot = strrchr( name, '.' );
|
||||
|
||||
if ( dot == (char*) 0 )
|
||||
return "text/plain; charset=iso-8859-1";
|
||||
|
||||
if ( strcmp( dot, ".html" ) == 0 || strcmp( dot, ".htm" ) == 0 )
|
||||
return "text/html; charset=iso-8859-1";
|
||||
|
||||
if ( strcmp( dot, ".jpg" ) == 0 || strcmp( dot, ".jpeg" ) == 0 )
|
||||
return "image/jpeg";
|
||||
|
||||
if ( strcmp( dot, ".gif" ) == 0 )
|
||||
return "image/gif";
|
||||
|
||||
if ( strcmp( dot, ".png" ) == 0 )
|
||||
return "image/png";
|
||||
|
||||
if ( strcmp( dot, ".css" ) == 0 )
|
||||
return "text/css";
|
||||
|
||||
if ( strcmp( dot, ".au" ) == 0 )
|
||||
return "audio/basic";
|
||||
|
||||
if ( strcmp( dot, ".wav" ) == 0 )
|
||||
return "audio/wav";
|
||||
|
||||
if ( strcmp( dot, ".avi" ) == 0 )
|
||||
return "video/x-msvideo";
|
||||
|
||||
if ( strcmp( dot, ".mov" ) == 0 || strcmp( dot, ".qt" ) == 0 )
|
||||
return "video/quicktime";
|
||||
|
||||
if ( strcmp( dot, ".mpeg" ) == 0 || strcmp( dot, ".mpe" ) == 0 )
|
||||
return "video/mpeg";
|
||||
|
||||
if ( strcmp( dot, ".vrml" ) == 0 || strcmp( dot, ".wrl" ) == 0 )
|
||||
return "model/vrml";
|
||||
|
||||
if ( strcmp( dot, ".midi" ) == 0 || strcmp( dot, ".mid" ) == 0 )
|
||||
return "audio/midi";
|
||||
|
||||
if ( strcmp( dot, ".mp3" ) == 0 )
|
||||
return "audio/mpeg";
|
||||
|
||||
if ( strcmp( dot, ".m4a" ) == 0 )
|
||||
return "audio/mp4";
|
||||
|
||||
if ( strcmp( dot, ".pdf" ) == 0 )
|
||||
return "application/pdf";
|
||||
|
||||
if ( strcmp( dot, ".ogg" ) == 0 )
|
||||
return "application/ogg";
|
||||
|
||||
if ( strcmp( dot, ".pac" ) == 0 )
|
||||
return "application/x-ns-proxy-autoconfig";
|
||||
|
||||
return "text/plain; charset=iso-8859-1";
|
||||
}
|
||||
|
||||
|
||||
static void strdecode( char* to, char* from )
|
||||
{
|
||||
for ( ; *from != '\0'; ++to, ++from )
|
||||
{
|
||||
if ( from[0] == '%' && isxdigit( from[1] ) && isxdigit( from[2] ) )
|
||||
{
|
||||
*to = hexit( from[1] ) * 16 + hexit( from[2] );
|
||||
from += 2;
|
||||
}
|
||||
else
|
||||
*to = *from;
|
||||
}
|
||||
*to = '\0';
|
||||
}
|
||||
|
||||
|
||||
static int hexit( char c )
|
||||
{
|
||||
if ( c >= '0' && c <= '9' )
|
||||
return c - '0';
|
||||
|
||||
if ( c >= 'a' && c <= 'f' )
|
||||
return c - 'a' + 10;
|
||||
|
||||
if ( c >= 'A' && c <= 'F' )
|
||||
return c - 'A' + 10;
|
||||
|
||||
//default
|
||||
return 0; /* shouldn't happen, we're guarded by isxdigit() */
|
||||
}
|
||||
|
||||
|
||||
static void strencode( char* to, size_t tosize, const char* from )
|
||||
{
|
||||
int tolen;
|
||||
|
||||
for ( tolen = 0; *from != '\0' && tolen + 4 < tosize; ++from )
|
||||
{
|
||||
if ( isalnum(*from) || strchr( "/_.-~", *from ) != (char*) 0 )
|
||||
{
|
||||
*to = *from;
|
||||
++to;
|
||||
++tolen;
|
||||
} else {
|
||||
sprintf( to, "%%%02x", (int) *from & 0xff );
|
||||
to += 3;
|
||||
tolen += 3;
|
||||
}
|
||||
}
|
||||
|
||||
*to = '\0';
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
char lower(const char a) {
|
||||
if (!isalpha(a)) return a;
|
||||
|
||||
if (!(a < 'z' && a > 'a')) {
|
||||
return a+32;
|
||||
} else {
|
||||
return a;
|
||||
}
|
||||
}
|
||||
|
||||
/* strcasecmp is not ANSI */
|
||||
int strcasecmp(const char *s1, const char *s2){
|
||||
size_t i;
|
||||
|
||||
for(i=0;; i++){
|
||||
if(!(lower(*(s1+i)) == lower(*(s2+i)) ) ) {
|
||||
return *(s1+i) - *(s2+i);
|
||||
}
|
||||
if(*(s1+i) == '\0'){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
25
CS4210/Project 3/common/http/http.h
Normal file
25
CS4210/Project 3/common/http/http.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <sys/types.h>
|
||||
#define BUFFERSIZE 1024 /* max size for recv buffer */
|
||||
#define LOOP_BOUNDS 2 // Tolerance of the recv() loop.
|
||||
|
||||
typedef struct _http_request {
|
||||
char method[10];
|
||||
char path[BUFFERSIZE];
|
||||
char protocol[15];
|
||||
} http_request;
|
||||
|
||||
|
||||
/* Forwards. */
|
||||
/* Note to Puyan: you do not declare static functions in the header file, kkthx */
|
||||
/*static void file_details( char* dir, char* name , FILE *socket_file);
|
||||
static void send_error( int status, char* title, char* extra_header, char* text, FILE *socket_file );
|
||||
static void send_headers( int status, char* title, char* extra_header, char* mime_type, off_t length, time_t mod, FILE *socket_file );
|
||||
static char* get_mime_type( char* name );
|
||||
static void strdecode( char* to, char* from );
|
||||
static int hexit( char c );
|
||||
static void strencode( char* to, size_t tosize, const char* from );*/
|
||||
|
||||
|
||||
void http_proto(int socket, char *request);
|
||||
int parse_request(char *request, http_request *package);
|
||||
|
||||
3
CS4210/Project 3/common/message/CVS/Entries
Normal file
3
CS4210/Project 3/common/message/CVS/Entries
Normal file
@@ -0,0 +1,3 @@
|
||||
/message.c/1.3/Sun Apr 2 10:06:57 2006//
|
||||
/message.h/1.3/Sun Apr 2 10:06:57 2006//
|
||||
D
|
||||
2
CS4210/Project 3/common/message/CVS/Entries.Extra
Normal file
2
CS4210/Project 3/common/message/CVS/Entries.Extra
Normal file
@@ -0,0 +1,2 @@
|
||||
/message.c////*///
|
||||
/message.h////*///
|
||||
2
CS4210/Project 3/common/message/CVS/Entries.Extra.Old
Normal file
2
CS4210/Project 3/common/message/CVS/Entries.Extra.Old
Normal file
@@ -0,0 +1,2 @@
|
||||
/message.c////*///
|
||||
/message.h////*///
|
||||
3
CS4210/Project 3/common/message/CVS/Entries.Old
Normal file
3
CS4210/Project 3/common/message/CVS/Entries.Old
Normal file
@@ -0,0 +1,3 @@
|
||||
/message.c/0/dummy timestamp//
|
||||
/message.h/0/dummy timestamp//
|
||||
D
|
||||
1
CS4210/Project 3/common/message/CVS/Repository
Normal file
1
CS4210/Project 3/common/message/CVS/Repository
Normal file
@@ -0,0 +1 @@
|
||||
CS4210/Project 3/common/message
|
||||
1
CS4210/Project 3/common/message/CVS/Root
Normal file
1
CS4210/Project 3/common/message/CVS/Root
Normal file
@@ -0,0 +1 @@
|
||||
:ext:asskoala@192.168.0.3:/usr/_CVS
|
||||
3
CS4210/Project 3/common/message/message.c
Normal file
3
CS4210/Project 3/common/message/message.c
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "message.h"
|
||||
|
||||
|
||||
12
CS4210/Project 3/common/message/message.h
Normal file
12
CS4210/Project 3/common/message/message.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef _MESSAGE_H_
|
||||
#define _MESSAGE_H_
|
||||
|
||||
typedef struct Request {
|
||||
int bufferIndex;
|
||||
} Request;
|
||||
|
||||
typedef struct Response {
|
||||
char data;
|
||||
} Response;
|
||||
|
||||
#endif
|
||||
3
CS4210/Project 3/common/networking/CVS/Entries
Normal file
3
CS4210/Project 3/common/networking/CVS/Entries
Normal file
@@ -0,0 +1,3 @@
|
||||
/networking.c/1.3/Sun Apr 2 10:06:57 2006//
|
||||
/networking.h/1.3/Sun Apr 2 10:06:57 2006//
|
||||
D
|
||||
2
CS4210/Project 3/common/networking/CVS/Entries.Extra
Normal file
2
CS4210/Project 3/common/networking/CVS/Entries.Extra
Normal file
@@ -0,0 +1,2 @@
|
||||
/networking.c////*///
|
||||
/networking.h////*///
|
||||
2
CS4210/Project 3/common/networking/CVS/Entries.Extra.Old
Normal file
2
CS4210/Project 3/common/networking/CVS/Entries.Extra.Old
Normal file
@@ -0,0 +1,2 @@
|
||||
/networking.c////*///
|
||||
/networking.h////*///
|
||||
3
CS4210/Project 3/common/networking/CVS/Entries.Old
Normal file
3
CS4210/Project 3/common/networking/CVS/Entries.Old
Normal file
@@ -0,0 +1,3 @@
|
||||
/networking.c/0/dummy timestamp//
|
||||
/networking.h/0/dummy timestamp//
|
||||
D
|
||||
1
CS4210/Project 3/common/networking/CVS/Repository
Normal file
1
CS4210/Project 3/common/networking/CVS/Repository
Normal file
@@ -0,0 +1 @@
|
||||
CS4210/Project 3/common/networking
|
||||
1
CS4210/Project 3/common/networking/CVS/Root
Normal file
1
CS4210/Project 3/common/networking/CVS/Root
Normal file
@@ -0,0 +1 @@
|
||||
:ext:asskoala@192.168.0.3:/usr/_CVS
|
||||
194
CS4210/Project 3/common/networking/networking.c
Normal file
194
CS4210/Project 3/common/networking/networking.c
Normal file
@@ -0,0 +1,194 @@
|
||||
#include "networking.h"
|
||||
#include "../defs.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#include <unistd.h> /* close() */
|
||||
#include <sys/socket.h> /* Socket Functions */
|
||||
#include <sys/types.h> /* Socket Datatypes */
|
||||
#include <netinet/in.h> /* IP Datatypes */
|
||||
#include <arpa/inet.h> /* Address Structs */
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Build a socket on the port_number parameter
|
||||
*/
|
||||
int ContructTCPSocket(unsigned short port_number)
|
||||
{
|
||||
int servSock; /* Server sock descriptor. */
|
||||
int opt; /* Reuse ocupied port */
|
||||
struct sockaddr_in ServAddr; /* Server Socket addr */
|
||||
struct sockaddr_in ClntAddr; /* Client Socket addr */
|
||||
|
||||
opt = REUSE_PORT; /* reuse port sockopt */
|
||||
/* Construct local */
|
||||
/* address structure */
|
||||
memset( &ServAddr, 0, sizeof(ServAddr) ); /* Zero serve struct */
|
||||
memset( &ClntAddr, 0, sizeof(ClntAddr) ); /* Zero client struct */
|
||||
ServAddr.sin_family = AF_INET; /* Inet addr family */
|
||||
ServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming iface */
|
||||
ServAddr.sin_port = htons(port_number); /* Local (server) port */
|
||||
|
||||
if ((servSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
|
||||
DieWithError("socket() failed"); /* create socket */
|
||||
|
||||
if (setsockopt(servSock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1)
|
||||
DieWithError("setsockopt() failed"); /* sockopt: reuse ports */
|
||||
|
||||
if (bind(servSock, (struct sockaddr *) &ServAddr, sizeof(ServAddr)) < 0)
|
||||
DieWithError("bind() failed"); /* bind to the port */
|
||||
|
||||
if (listen(servSock, MAXPENDING) < 0)
|
||||
DieWithError("listen() failed");
|
||||
|
||||
return servSock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Accept a connection on the socket passed in
|
||||
*/
|
||||
int AcceptConnection(int server_socket)
|
||||
{
|
||||
int clntSock; /* client sock descriptor. */
|
||||
struct sockaddr_in ClntAddr; /* Client Socket addr */
|
||||
unsigned int ClntLen; /* client address *
|
||||
* struct length */
|
||||
ClntLen = sizeof(ClntAddr); /* Client addr length */
|
||||
|
||||
VPRINTF(("[PRODUCER] Waiting to accept a connection\n"));
|
||||
|
||||
|
||||
if ((clntSock = accept(server_socket, (struct sockaddr *) &ClntAddr, &ClntLen)) < 0) {
|
||||
//DieWithError("accept() failed"); /* Wait for a client to connect */
|
||||
clntSock = -1; //negative socket, so it knows to ignore this connection
|
||||
}
|
||||
|
||||
VPRINTF(("Handling client %s\n", inet_ntoa(ClntAddr.sin_addr)));
|
||||
|
||||
return clntSock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive until there's nothing left to receive
|
||||
* !! Fully Dynamic, must free the returned value when done
|
||||
*/
|
||||
int uber_recv(int sock, size_t max_to_receive, char *delimit, char **ppcData) {
|
||||
char *curToRecv = malloc(max_to_receive);
|
||||
|
||||
char *dgramPtr;
|
||||
int totalBytesRecv;
|
||||
int newBytesRecv;
|
||||
int i;
|
||||
|
||||
if (NULL == curToRecv) VPRINTF(("malloc() failed\n"));
|
||||
memset(curToRecv, 0, sizeof(char)*max_to_receive);
|
||||
|
||||
{ // Begin For Loop
|
||||
for(i=0,totalBytesRecv=0, newBytesRecv=0, dgramPtr=curToRecv;
|
||||
totalBytesRecv < max_to_receive; totalBytesRecv+=newBytesRecv,i++) {
|
||||
|
||||
//VPRINTF(("Receiving %d Bytes. %d Bytes Total.\n",
|
||||
// newBytesRecv, totalBytesRecv));
|
||||
|
||||
if(((newBytesRecv = recv(sock, dgramPtr,
|
||||
max_to_receive - totalBytesRecv, 0)) <= 0)) {
|
||||
VPRINTF(("recv() failed\n"));
|
||||
free(curToRecv);
|
||||
return -1;
|
||||
} else {
|
||||
char *curToRecv_ptr;
|
||||
char *recv_tok;
|
||||
dgramPtr += newBytesRecv;
|
||||
//VPRINTF(("%s\n", curToRecv));
|
||||
if (NULL==delimit) {
|
||||
continue;
|
||||
} else if(NULL != (recv_tok = strtok_r(curToRecv, delimit, &curToRecv_ptr))) {
|
||||
*ppcData = curToRecv;
|
||||
return totalBytesRecv;
|
||||
}
|
||||
}
|
||||
} // End For Loop
|
||||
}
|
||||
*ppcData = curToRecv;
|
||||
return totalBytesRecv;
|
||||
}
|
||||
|
||||
int http_recv(int sock, size_t max_to_receive, char **ppcData) {
|
||||
char *curToRecv;
|
||||
|
||||
char *dgramPtr;
|
||||
int totalBytesRecv;
|
||||
int newBytesRecv;
|
||||
int i;
|
||||
|
||||
//check if socket closed
|
||||
|
||||
|
||||
curToRecv = malloc(max_to_receive);
|
||||
if (NULL == curToRecv) VPRINTF(("malloc() failed\n"));
|
||||
memset(curToRecv, 0, sizeof(char)*max_to_receive);
|
||||
|
||||
{ // Begin For Loop
|
||||
for(i=0,totalBytesRecv=0, newBytesRecv=0, dgramPtr=curToRecv;
|
||||
totalBytesRecv < max_to_receive; totalBytesRecv+=newBytesRecv,i++) {
|
||||
|
||||
//VPRINTF(("Receiving %d Bytes. %d Bytes Total.\n",
|
||||
// newBytesRecv, totalBytesRecv));
|
||||
|
||||
if(((newBytesRecv = recv(sock, dgramPtr,
|
||||
max_to_receive - totalBytesRecv, 0)) <= 0)) {
|
||||
VPRINTF(("recv() failed\n"));
|
||||
free(curToRecv);
|
||||
return 0;
|
||||
} /*else {
|
||||
char *curToRecv_ptr;
|
||||
dgramPtr += newBytesRecv;
|
||||
//VPRINTF(("%s\n", curToRecv));
|
||||
|
||||
if((NULL != strstr(curToRecv, "\r\n0\r\n\r\n"))) {
|
||||
printf("Got End of HTTP Receive\n");
|
||||
*ppcData = curToRecv;
|
||||
return 0;
|
||||
}
|
||||
}*/
|
||||
} // End For Loop
|
||||
}
|
||||
*ppcData = curToRecv;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int createTCPSocket(char *ipaddr, unsigned short server_port)
|
||||
{
|
||||
|
||||
int sock; /* Socket descriptor */
|
||||
struct sockaddr_in ServAddr; /* Address Structure */
|
||||
|
||||
#ifdef _WIN32
|
||||
WSADATA wsaData; /* Winsock struct. */
|
||||
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0)/* Winsock 2.0 DLL. */
|
||||
DieWithError("WSAStartup() failed");
|
||||
#endif
|
||||
|
||||
if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
|
||||
DieWithError("socket() failed");
|
||||
|
||||
memset(&ServAddr, 0, sizeof(ServAddr));
|
||||
ServAddr.sin_family = AF_INET;
|
||||
ServAddr.sin_addr.s_addr = inet_addr(ipaddr);
|
||||
ServAddr.sin_port = htons(server_port);
|
||||
|
||||
if (connect(sock, (struct sockaddr *) &ServAddr, sizeof(ServAddr)) < 0) {
|
||||
return -1;
|
||||
} else {
|
||||
return sock;
|
||||
}
|
||||
}
|
||||
|
||||
18
CS4210/Project 3/common/networking/networking.h
Normal file
18
CS4210/Project 3/common/networking/networking.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef _NETWORKING_H_
|
||||
#define _NETWORKING_H_
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#define MAXPENDING 5 /* Max Requests */
|
||||
#define REUSE_PORT 1
|
||||
|
||||
int ContructTCPSocket(unsigned short port_number);
|
||||
int AcceptConnection(int server_socket);
|
||||
int uber_recv(int sock, size_t max_to_receive, char *delimit, char** ppcData);
|
||||
|
||||
int http_recv(int sock, size_t max_to_receive, char **ppcData);
|
||||
|
||||
//From client
|
||||
int createTCPSocket(char *ipaddr, unsigned short server_port);
|
||||
|
||||
#endif
|
||||
3
CS4210/Project 3/common/shared_memory/CVS/Entries
Normal file
3
CS4210/Project 3/common/shared_memory/CVS/Entries
Normal file
@@ -0,0 +1,3 @@
|
||||
/shared_memory.c/1.3/Sun Apr 2 10:06:57 2006//
|
||||
/shared_memory.h/1.3/Sun Apr 2 10:06:57 2006//
|
||||
D
|
||||
2
CS4210/Project 3/common/shared_memory/CVS/Entries.Extra
Normal file
2
CS4210/Project 3/common/shared_memory/CVS/Entries.Extra
Normal file
@@ -0,0 +1,2 @@
|
||||
/shared_memory.c////*///
|
||||
/shared_memory.h////*///
|
||||
@@ -0,0 +1,2 @@
|
||||
/shared_memory.c////*///
|
||||
/shared_memory.h////*///
|
||||
3
CS4210/Project 3/common/shared_memory/CVS/Entries.Old
Normal file
3
CS4210/Project 3/common/shared_memory/CVS/Entries.Old
Normal file
@@ -0,0 +1,3 @@
|
||||
/shared_memory.c/0/dummy timestamp//
|
||||
/shared_memory.h/0/dummy timestamp//
|
||||
D
|
||||
1
CS4210/Project 3/common/shared_memory/CVS/Repository
Normal file
1
CS4210/Project 3/common/shared_memory/CVS/Repository
Normal file
@@ -0,0 +1 @@
|
||||
CS4210/Project 3/common/shared_memory
|
||||
1
CS4210/Project 3/common/shared_memory/CVS/Root
Normal file
1
CS4210/Project 3/common/shared_memory/CVS/Root
Normal file
@@ -0,0 +1 @@
|
||||
:ext:asskoala@192.168.0.3:/usr/_CVS
|
||||
262
CS4210/Project 3/common/shared_memory/shared_memory.c
Normal file
262
CS4210/Project 3/common/shared_memory/shared_memory.c
Normal file
@@ -0,0 +1,262 @@
|
||||
#include "shared_memory.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/sem.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
static shmemNode *head;
|
||||
static shmemNode *tail;
|
||||
|
||||
int shmid[NBUFF]; /* Shared Memory Segment Array */
|
||||
char* buffptr[NBUFF]; /* Used for each process to attach to */
|
||||
int semprox; /* Proxy Shared Memory Semaphore */
|
||||
int semserv; /* Server Shared Memory Semaphore */
|
||||
|
||||
static pthread_mutex_t shmem_mutex;
|
||||
static pthread_cond_t shmem_cond;
|
||||
|
||||
void fast_exit(char* error) {
|
||||
fprintf(stderr, "%s", error);
|
||||
destroy_shared_memory();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve a shared memory segment for use
|
||||
*
|
||||
* This is where it locks/waits
|
||||
*/
|
||||
shmemNode *getSharedMemorySegment() {
|
||||
shmemNode *toRet;
|
||||
|
||||
//printf("Locking...");
|
||||
pthread_mutex_lock(&shmem_mutex);
|
||||
//printf("Done\n");
|
||||
|
||||
while (!head) {
|
||||
//printf("Head is Null\n");
|
||||
pthread_cond_wait(&shmem_cond, &shmem_mutex);
|
||||
}
|
||||
|
||||
toRet = head;
|
||||
head = head->next;
|
||||
|
||||
toRet->next = NULL;
|
||||
|
||||
pthread_mutex_unlock(&shmem_mutex);
|
||||
pthread_cond_signal(&shmem_cond);
|
||||
|
||||
//printf("Returning..\n");
|
||||
return toRet;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release a shared memory segment into the pool
|
||||
*
|
||||
*/
|
||||
void releaseSharedMemorySegment(shmemNode* node) {
|
||||
pthread_mutex_lock(&shmem_mutex);
|
||||
|
||||
if (!head) {
|
||||
head = tail = node;
|
||||
head->next = NULL;
|
||||
} else {
|
||||
tail->next = node;
|
||||
tail = node;
|
||||
tail->next = NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&shmem_mutex);
|
||||
pthread_cond_signal(&shmem_cond);
|
||||
}
|
||||
|
||||
/*
|
||||
* NO locking done here, must be initialized before shared memory and threads
|
||||
* can be used.
|
||||
* Otherwise, there would be a deadlock. non-runtime Race > deadlock.
|
||||
*
|
||||
* This data structure is used by the proxy
|
||||
*/
|
||||
void init_queue() {
|
||||
int i;
|
||||
|
||||
printf("** Initializing Queue\n");
|
||||
|
||||
/* Initialize Mutexes */
|
||||
pthread_mutex_init(&shmem_mutex, NULL);
|
||||
pthread_cond_init(&shmem_cond,NULL);
|
||||
|
||||
/* Initialize Queue */
|
||||
head = tail = NULL;
|
||||
|
||||
for (i=0; i < NBUFF; i++) {
|
||||
shmemNode *temp;
|
||||
|
||||
temp = malloc(sizeof(shmemNode));
|
||||
|
||||
if (!temp) {
|
||||
printf("Malloc failed (init_queue), that stinks.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
temp->shmid = shmid[i];
|
||||
temp->buff = buffptr[i];
|
||||
temp->semIndex = i;
|
||||
temp->next = NULL;
|
||||
|
||||
if (!head) {
|
||||
head = tail = temp;
|
||||
} else {
|
||||
tail->next = temp;
|
||||
tail = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize shared memory and semaphores
|
||||
*/
|
||||
int init_shared_memory() {
|
||||
int i;
|
||||
|
||||
/* Initialize and attach Shared Memory Segments */
|
||||
for (i = 0; i < NBUFF; ++i) {
|
||||
shmid[i] = shmget(SHMKEY+i, BUFFSIZE, PERMS | IPC_CREAT);
|
||||
buffptr[i] = shmat(shmid[i], (char*)0, 0);
|
||||
|
||||
if (shmid[i] < 0) {
|
||||
fprintf(stderr, "Couldn't allocate Shared Memory Segment %d\n", i);
|
||||
for (; i >= 0; --i) {
|
||||
shmctl(shmid[i], IPC_RMID, NULL);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
semserv = semget(SEMSERV, NBUFF, PERMS | IPC_CREAT);
|
||||
|
||||
if (semserv == -1) {
|
||||
semserv_err:
|
||||
printf("Error %d\n", errno);
|
||||
fast_exit("Failed to initialize semserv.\n");
|
||||
}
|
||||
|
||||
for (i=0; i < NBUFF; i++) {
|
||||
if (semctl(semserv, i, SETVAL, 1) == -1) {
|
||||
goto semserv_err;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
semprox = semget(SEMPROX, NBUFF, PERMS | IPC_CREAT);
|
||||
if (semprox == -1) {
|
||||
semprox_err:
|
||||
printf("Error %d\n", errno);
|
||||
fast_exit("Failed to initialize semprox.\n");
|
||||
}
|
||||
for (i=0; i < NBUFF; i++) {
|
||||
if (semctl(semprox, i, SETVAL, 0) == -1) {
|
||||
goto semprox_err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach the process to the shared memory segments
|
||||
*
|
||||
* The queue is used by the client, so it is initialized here
|
||||
*
|
||||
*/
|
||||
int attach_shared_memory() {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NBUFF; ++i) {
|
||||
shmid[i] = shmget(SHMKEY+i, BUFFSIZE, 0);
|
||||
buffptr[i] = shmat(shmid[i], (char*)0, 0);
|
||||
|
||||
if (shmid[i] < 0) {
|
||||
fprintf(stderr, "Couldn't attach Shared Memory Segment %d\n", i);
|
||||
for (; i >= 0; --i) {
|
||||
shmctl(SHMKEY+i, IPC_RMID, NULL);
|
||||
}
|
||||
return shmid[i];
|
||||
}
|
||||
}
|
||||
|
||||
semserv = semget(SEMSERV, 0, PERMS);
|
||||
|
||||
if (semserv == -1) {
|
||||
printf("Error %d\n", errno);
|
||||
fast_exit("Failed to initialize semserv.\n");
|
||||
}
|
||||
|
||||
semprox = semget(SEMPROX, 0, PERMS);
|
||||
if (semprox == -1) {
|
||||
printf("Error %d\n", errno);
|
||||
fast_exit("Failed to initialize semprox.\n");
|
||||
}
|
||||
|
||||
init_queue();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy the shared memory segments
|
||||
*/
|
||||
void destroy_shared_memory() {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NBUFF; ++i) {
|
||||
if (shmdt(buffptr[i]) < 0) {
|
||||
fprintf(stderr, "Failed to detach Shared Memory segment %d\n", i);
|
||||
}
|
||||
if (shmctl(shmid[i], IPC_RMID, NULL) < 0) {
|
||||
fprintf(stderr, "Failed to free Shared Memory segment %d\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
if (semctl(semprox, 0, IPC_RMID) == -1) {
|
||||
fprintf(stderr, "Failed to cleanup semprox.\n");
|
||||
}
|
||||
if (semctl(semserv, 0, IPC_RMID) == -1) {
|
||||
fprintf(stderr, "Failed to cleanup semserv.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Detach self from shared memory
|
||||
*/
|
||||
void detach_shared_memory() {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NBUFF; ++i) {
|
||||
if (shmdt(buffptr[i]) < 0) {
|
||||
fprintf(stderr, "Failed to free Shared Memory segment %d\n", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *attach_shmem(int index) {
|
||||
return shmat(SHMKEY+index, (void*)0, 0);
|
||||
}
|
||||
|
||||
int detach_shmem(void *ptr) {
|
||||
return shmdt(ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
51
CS4210/Project 3/common/shared_memory/shared_memory.h
Normal file
51
CS4210/Project 3/common/shared_memory/shared_memory.h
Normal file
@@ -0,0 +1,51 @@
|
||||
#ifndef _SHARED_MEMORY_H_
|
||||
#define _SHARED_MEMORY_H_
|
||||
|
||||
#include <sys/shm.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#define NBUFF 4 /* Number of Shared Memory Segments */
|
||||
|
||||
#define SHMKEY ((key_t) 7890) /* Shared Memory Key */
|
||||
#define SEMPROX ((key_t) 7891) /* Shared Memory Proxy Semaphore Key */
|
||||
#define SEMSERV ((key_t) 7892) /* Shared Memory Server Semaphore Key */
|
||||
|
||||
#define PERMS 0666 /* Shared Memory Permissions */
|
||||
#define BUFFSIZE 1024 /* Buffer Size (Bytes) */
|
||||
|
||||
extern int shmid[NBUFF]; /* Shared Memory Segment Array */
|
||||
extern char* buffptr[NBUFF]; /* Used for each process to attach to */
|
||||
extern int semprox; /* Proxy Shared Memory Semaphore */
|
||||
extern int semserv; /* Server Shared Memory Semaphore */
|
||||
|
||||
typedef struct shmemNode {
|
||||
int shmid;
|
||||
int semIndex;
|
||||
char* buff;
|
||||
struct shmemNode *next;
|
||||
} shmemNode;
|
||||
|
||||
|
||||
/////////////
|
||||
// Getters //
|
||||
/////////////
|
||||
int get_semserv();
|
||||
int get_semprox();
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
// Methods //
|
||||
//god I wish we could use C++ //
|
||||
////////////////////////////////
|
||||
int init_shared_memory();
|
||||
int attach_shared_memory();
|
||||
|
||||
void destroy_shared_memory();
|
||||
void detach_shared_memory();
|
||||
|
||||
void *attach_to_shmem(int index);
|
||||
|
||||
shmemNode *getSharedMemorySegment();
|
||||
void releaseSharedMemorySegment(shmemNode* node);
|
||||
|
||||
#endif
|
||||
3
CS4210/Project 3/common/strtok_r/CVS/Entries
Normal file
3
CS4210/Project 3/common/strtok_r/CVS/Entries
Normal file
@@ -0,0 +1,3 @@
|
||||
/strtok_r.c/1.3/Sun Apr 2 10:06:57 2006//
|
||||
/strtok_r.h/1.3/Sun Apr 2 10:06:57 2006//
|
||||
D
|
||||
2
CS4210/Project 3/common/strtok_r/CVS/Entries.Extra
Normal file
2
CS4210/Project 3/common/strtok_r/CVS/Entries.Extra
Normal file
@@ -0,0 +1,2 @@
|
||||
/strtok_r.c////*///
|
||||
/strtok_r.h////*///
|
||||
2
CS4210/Project 3/common/strtok_r/CVS/Entries.Extra.Old
Normal file
2
CS4210/Project 3/common/strtok_r/CVS/Entries.Extra.Old
Normal file
@@ -0,0 +1,2 @@
|
||||
/strtok_r.c////*///
|
||||
/strtok_r.h////*///
|
||||
3
CS4210/Project 3/common/strtok_r/CVS/Entries.Old
Normal file
3
CS4210/Project 3/common/strtok_r/CVS/Entries.Old
Normal file
@@ -0,0 +1,3 @@
|
||||
/strtok_r.c/0/dummy timestamp//
|
||||
/strtok_r.h/0/dummy timestamp//
|
||||
D
|
||||
1
CS4210/Project 3/common/strtok_r/CVS/Repository
Normal file
1
CS4210/Project 3/common/strtok_r/CVS/Repository
Normal file
@@ -0,0 +1 @@
|
||||
CS4210/Project 3/common/strtok_r
|
||||
1
CS4210/Project 3/common/strtok_r/CVS/Root
Normal file
1
CS4210/Project 3/common/strtok_r/CVS/Root
Normal file
@@ -0,0 +1 @@
|
||||
:ext:asskoala@192.168.0.3:/usr/_CVS
|
||||
48
CS4210/Project 3/common/strtok_r/strtok_r.c
Normal file
48
CS4210/Project 3/common/strtok_r/strtok_r.c
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "include/strtok_r.h"
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
char *strtok_r(char *s, const char *delim, char** s3)
|
||||
{
|
||||
char *pR;
|
||||
short bDone=0;
|
||||
size_t i,j;
|
||||
|
||||
if(s != NULL){
|
||||
*s3 = s;
|
||||
}
|
||||
if(**s3 == '\0'){
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(;;){
|
||||
bDone = 1;
|
||||
for(j=0; *(delim+j) != '\0'; j++){
|
||||
if(**s3 == *(delim+j)){
|
||||
**s3 = '\0';
|
||||
(*s3)+=1;
|
||||
bDone = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(bDone == 1){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; *(*s3+i) != '\0'; i++){
|
||||
|
||||
for(j=0; *(delim+j) != '\0'; j++){
|
||||
if(*(*s3+i) == *(delim+j)){
|
||||
pR = *s3;
|
||||
*(*s3+i) = '\0';
|
||||
*s3 += i+1;
|
||||
|
||||
return pR;
|
||||
}
|
||||
}
|
||||
}
|
||||
pR = *s3;
|
||||
*s3 += i;
|
||||
return pR;
|
||||
}
|
||||
13
CS4210/Project 3/common/strtok_r/strtok_r.h
Normal file
13
CS4210/Project 3/common/strtok_r/strtok_r.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef _STRTOK_R_H_
|
||||
#define _STRTOK_R_H_
|
||||
|
||||
/*
|
||||
* String Tokenizer! :)
|
||||
* Toke up some strings to get
|
||||
*
|
||||
* s = string to toke
|
||||
* delim = deliminator, thing to delim
|
||||
*/
|
||||
char *strtok_r(char *s, const char *delim, char** s3);
|
||||
|
||||
#endif
|
||||
3
CS4210/Project 3/common/thread_pool/CVS/Entries
Normal file
3
CS4210/Project 3/common/thread_pool/CVS/Entries
Normal file
@@ -0,0 +1,3 @@
|
||||
/thread_pool.c/1.3/Sun Apr 2 10:06:57 2006//
|
||||
/thread_pool.h/1.3/Sun Apr 2 10:06:57 2006//
|
||||
D
|
||||
2
CS4210/Project 3/common/thread_pool/CVS/Entries.Extra
Normal file
2
CS4210/Project 3/common/thread_pool/CVS/Entries.Extra
Normal file
@@ -0,0 +1,2 @@
|
||||
/thread_pool.c////*///
|
||||
/thread_pool.h////*///
|
||||
@@ -0,0 +1,2 @@
|
||||
/thread_pool.c////*///
|
||||
/thread_pool.h////*///
|
||||
3
CS4210/Project 3/common/thread_pool/CVS/Entries.Old
Normal file
3
CS4210/Project 3/common/thread_pool/CVS/Entries.Old
Normal file
@@ -0,0 +1,3 @@
|
||||
/thread_pool.c/0/dummy timestamp//
|
||||
/thread_pool.h/0/dummy timestamp//
|
||||
D
|
||||
1
CS4210/Project 3/common/thread_pool/CVS/Repository
Normal file
1
CS4210/Project 3/common/thread_pool/CVS/Repository
Normal file
@@ -0,0 +1 @@
|
||||
CS4210/Project 3/common/thread_pool
|
||||
1
CS4210/Project 3/common/thread_pool/CVS/Root
Normal file
1
CS4210/Project 3/common/thread_pool/CVS/Root
Normal file
@@ -0,0 +1 @@
|
||||
:ext:asskoala@192.168.0.3:/usr/_CVS
|
||||
155
CS4210/Project 3/common/thread_pool/thread_pool.c
Normal file
155
CS4210/Project 3/common/thread_pool/thread_pool.c
Normal file
@@ -0,0 +1,155 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "thread_pool.h"
|
||||
#include <pthread.h>
|
||||
#include "../defs.h"
|
||||
|
||||
|
||||
/////////////////////////////////
|
||||
// Used by all data structures //
|
||||
/////////////////////////////////
|
||||
|
||||
static unsigned int length = 0;
|
||||
|
||||
static pthread_mutex_t mutex;
|
||||
static pthread_cond_t isReady;
|
||||
|
||||
///////////////////////
|
||||
// Linked List Queue //
|
||||
///////////////////////
|
||||
|
||||
typedef struct QUEUE {
|
||||
int socket;
|
||||
struct QUEUE* next;
|
||||
} qMember;
|
||||
|
||||
qMember* qHead = NULL;
|
||||
qMember* qTail = NULL;
|
||||
|
||||
pthread_mutex_t* get_mutex()
|
||||
{
|
||||
return &mutex;
|
||||
}
|
||||
|
||||
pthread_cond_t* get_is_ready()
|
||||
{
|
||||
return &isReady;
|
||||
}
|
||||
|
||||
void qAdd(int socket) {
|
||||
qMember* newNode = malloc(sizeof(qMember));
|
||||
|
||||
VPRINTF(("Adding socket: %d\n", socket));
|
||||
|
||||
if (!newNode) { printf("Malloc failed, qAdd\n"); exit(1); }
|
||||
|
||||
newNode->next = NULL;
|
||||
newNode->socket = socket;
|
||||
|
||||
pthread_mutex_lock(get_mutex());
|
||||
|
||||
if (!qHead) {
|
||||
qTail = qHead = newNode;
|
||||
length++;
|
||||
} else {
|
||||
qTail->next = newNode;
|
||||
qTail = qTail->next;
|
||||
length++;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(get_mutex());
|
||||
pthread_cond_signal(get_is_ready());
|
||||
|
||||
}
|
||||
|
||||
int qRemove() {
|
||||
int toRet; //Socket to return
|
||||
qMember* temp;
|
||||
|
||||
pthread_mutex_lock(get_mutex()); //Lock mutex
|
||||
|
||||
while (!qHead) {
|
||||
pthread_cond_wait( get_is_ready(), get_mutex() ); //No requests waiting
|
||||
}
|
||||
|
||||
toRet = qHead->socket; //retrieve socket
|
||||
VPRINTF(("Removing socket: %d\n", toRet));
|
||||
|
||||
//Fix the list
|
||||
temp = qHead;
|
||||
qHead = qHead->next;
|
||||
length--;
|
||||
|
||||
//Fine grain lock, release lock before freeing old node
|
||||
pthread_mutex_unlock(get_mutex());
|
||||
|
||||
free(temp);
|
||||
|
||||
return toRet;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wrappers
|
||||
*/
|
||||
void addSocket(int socket) {
|
||||
#ifdef LLQ
|
||||
qAdd(socket);
|
||||
#else
|
||||
qAdd(socket);
|
||||
#endif
|
||||
}
|
||||
|
||||
int removeSocket() {
|
||||
#ifdef LLQ
|
||||
return qRemove();
|
||||
#else
|
||||
return qRemove();
|
||||
#endif
|
||||
}
|
||||
|
||||
unsigned int size() {
|
||||
return length;
|
||||
}
|
||||
|
||||
void init_synch() {
|
||||
pthread_mutex_init(get_mutex(), NULL);
|
||||
pthread_cond_init(get_is_ready(),NULL);
|
||||
}
|
||||
|
||||
void init_thread_pool(unsigned short *port_num, int maxThreads,
|
||||
void *(*producer)(void*),
|
||||
void *(*consumer)(void*),
|
||||
void *args)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!port_num) { printf("NULL Port Number\n"); exit(1); }
|
||||
|
||||
init_synch();
|
||||
|
||||
printf("** Initializing Thread Pool\n");
|
||||
VPRINTF(("*** Making %d threads on port %d\n",maxThreads,port_num));
|
||||
fflush(stdout);
|
||||
|
||||
//initialize producer
|
||||
producerThread = malloc(sizeof(pthread_t));
|
||||
if (!producerThread) { exit(1); }
|
||||
|
||||
printf("*** Listening on Port: %d\n", *port_num);
|
||||
|
||||
pthread_create(producerThread, NULL, producer, port_num);
|
||||
|
||||
//Initialize consumers
|
||||
consumerList = malloc(sizeof(pthread_t*)*maxThreads);
|
||||
|
||||
for (i=0; i < maxThreads; i++) {
|
||||
consumerList[i] = malloc(sizeof(pthread_t));
|
||||
|
||||
if (pthread_create(consumerList[i], NULL, consumer, args)) {
|
||||
printf("Error creating thread %d\n",i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
29
CS4210/Project 3/common/thread_pool/thread_pool.h
Normal file
29
CS4210/Project 3/common/thread_pool/thread_pool.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef _THREAD_POOL_H_
|
||||
#define _THREAD_POOL_H_
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "../pthreads/include/pthread.h"
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Variables
|
||||
*/
|
||||
|
||||
pthread_t **consumerList;
|
||||
pthread_t *producerThread;
|
||||
|
||||
/*
|
||||
* Methods
|
||||
*/
|
||||
void addSocket(int);
|
||||
int removeSocket();
|
||||
void init_thread_pool(unsigned short*, int,
|
||||
void *(*producer)(void*),
|
||||
void *(*consumer)(void*),
|
||||
void *args);
|
||||
unsigned int size();
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user