//
//protocol.c
//
//
//-UserX 2001/11/13
#include <stdlib.h>
#include <string.h>
#include "misc/compat.h"
#include "net/protocol.h"
#include "pipe/pipe.h"
#include "pipeface/pipeface.h"
#include "base/str.h"
#include "base/strarray.h"
#include "base/logger.h"
#include "net/sock.h"
#include "net/protocfg.h"
#include "base/array.h"
PipeProtocolEntry blankpipeprotocolentry = BLANKPIPEFACEPROTOCOLENTRY;
PipeFaceProtocolEntry blankpipefaceprotocolentry = BLANKPIPEFACEPROTOCOLENTRY;
PipeProtocolArrayHandle *pparray = NULL;
PipeFaceProtocolArrayHandle *pfparray = NULL;
void protocolInit(void) {
if(pparray == NULL) {
pparray = (PipeProtocolArrayHandle *)arrayMake(sizeof(PipeProtocolEntry), 0, &blankpipeprotocolentry, NULL, NULL);
}
if(pfparray == NULL) {
pfparray = (PipeFaceProtocolArrayHandle *)arrayMake(sizeof(PipeFaceProtocolEntry), 0, &blankpipefaceprotocolentry, NULL, NULL);
}
}
void protocolAddPipeList(PipeProtocolEntry *ppelist) {
int i;
int j;
if(ppelist == NULL) {
return;
}
protocolInit();
for(i = 0; ppelist[i].pipename != NULL; i++) {
j = pparray->size;
arrayInsert((ArrayHandle *)pparray, pparray->size, 1);
pparray->data[j] = ppelist[i];
}
}
void protocolAddPipeFaceList(PipeFaceProtocolEntry *pfpelist) {
int i;
int j;
if(pfpelist == NULL) {
return;
}
protocolInit();
for(i = 0; pfpelist[i].pipename != NULL; i++) {
j = pfparray->size;
arrayInsert((ArrayHandle *)pfparray, pfparray->size, 1);
pfparray->data[j] = pfpelist[i];
}
}
void protocolClearPipeList(void) {
protocolInit();
arrayDelete((ArrayHandle *)pparray, 0, pparray->size);
}
void protocolClearPipeFaceList(void) {
protocolInit();
arrayDelete((ArrayHandle *)pfparray, 0, pfparray->size);
}
Pipe *protocolGetPipe(char *pipename, char *options) {
int i;
protocolInit();
for(i = 0; i <= pparray->size; i++) {
if(stringCaseCompare(pparray->data[i].pipename, pipename) == 0) {
return (pparray->data[i].make)(pipename, options);
}
}
LOGERROR(stringJoinMany("Pipe type \"",
pipename,
"\" not found.",
NULL));
return NULL;
/*
switch(stringIntPairSearch(pipelist, pipename)) {
case PL_CRYPT:
return pipecryptMake(options);
case PL_STEADY:
return pipesteadyMake(options);
case PL_SPURT:
return pipespurtMake(options);
case PL_DUMMY:
return pipedummyMake(options);
case PL_BACK:
return pipebackwardMake(options);
case -1:
//todo: checking of available masquerading protocols
if(stringIntPairSearch(pipemasqlist, pipename) != -1) {
pipemasqMake(pipename);
}
LOGERROR(stringJoinMany("Pipe type \"",
pipename,
"\" not found.",
NULL));
return NULL;
default:
LOGERROR(stringJoinMany("Internal error, pipe type \"",
pipename,
"\" found but unhandled by code.",
NULL));
return NULL;
}
*/
}
PipeFace *protocolGetPipeFace(char *pipefacename, char *options) {
int i;
protocolInit();
for(i = 0; i <= pfparray->size; i++) {
if(stringCaseCompare(pfparray->data[i].pipename, pipefacename) == 0) {
return (pfparray->data[i].make)(pipefacename, options);
}
}
LOGERROR(stringJoinMany("Pipeface type \"",
pipefacename,
"\" not found.",
NULL));
return NULL;
/*
switch(stringIntPairSearch(pipefacelist, pipefacename)) {
case PFL_CORE:
case PFL_RAW:
return pfcoreMake(options);
case PFL_VIRC:
return pfvircMake(options);
case -1:
LOGERROR(stringJoinMany("Pipeface type \"",
pipefacename,
"\" not found.",
NULL));
return NULL;
default:
LOGERROR(stringJoinMany("Internal error pipeface type \"",
pipefacename,
"\" found but unhandled by code.",
NULL));
return NULL;
}
*/
}
//builds a pipe chain attached to an existing socket
PipeFace *protocolBuildPipe(SockHandle *sh, char *protocol) {
char *s;
char *p;
Pipe *newpipe = NULL;
Pipe *backpipe = &sh->IOPipe;
PipeFace *pf = NULL;
if(sh == NULL) {
return NULL;
}
if(isStringBlank(protocol)) {
LOGERROR("Missing protocol string (check for missing 'protocol' or 'networkprotocol' settings).");
return NULL;
}
//todo: validate protocol string
s = stringCopy(protocol);
for(p = stringSplit(s, ":"); !isStringBlank(s); p = stringSplit(s, ":")) {
//todo:error checking
newpipe = protocolGetPipe(p, ""); //todo: extract options
if(newpipe == NULL) {
newpipe = backpipe;
while(newpipe != &sh->IOPipe) {
backpipe = newpipe->backPipe;
pipeDetach(newpipe);
newpipe = backpipe;
}
return NULL;
}
pipeAttach(backpipe, newpipe);
backpipe = newpipe;
stringFree(p);
}
stringFree(s);
//todo: error checking
pf = protocolGetPipeFace(p, ""); //todo: extract options
pipefaceInit(pf, backpipe);
stringFree(p);
return pf;
}
syntax highlighted by Code2HTML, v. 0.9.1