I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit dae6be14 authored by polecat's avatar polecat Committed by zzz
Browse files

I removed those dumb platform specific makefiles. They weren't doing what...

I removed those dumb platform specific makefiles.  They weren't doing what they ought anyway.  If there are platform specific issues, someone please tell me and I'll provide support for it here.  Or patch it yourself.
And this is the big "Fix the Parser" patch.  It turns the sam_parse function in src/parse.c into something that actually works.  Generating the argument list from an incoming SAM thingy is a bit memory churn-y; perhaps when I have time I'll replace all those strdups with structures that simply track the (start,end) indices.
Oh and also I moved i2p-ping to the new system.  Which required 0 change in code.  All I did was fix the Makefile, and add shared library libtool support.  Anyway, so enjoy folks.  It's rare I'm this productive
- polecat
parent 20cec857
No related branches found
No related tags found
No related merge requests found
FLAGS+=-g
CFLAGS+=$(FLAGS)
LDFLAGS+=$(FLAGS)
OBJS:=obj/sam.lo obj/strl.lo obj/parse.lo obj/tinystring.lo
DEPS:=$(patsubst obj/%.lo, .deps/%.d, $(OBJS))
DESTDIR:=$(if $(DESTDIR),$(DESTDIR)/lib,/usr/lib)
MAKEFLAGS=-s -r
PERL=$(shell which perl 2>/dev/null)
ifneq ($(PERL),)
STATUS=$(PERL) ./status
else
STATUS=echo
endif
LIBTOOL_LOG=libtool.log
all:: cleanlog .deps/finish
cleanlog:
echo >$(LIBTOOL_LOG)
lib/libsam.so: obj/libsam.la
libtool --mode=install install $^ `pwd`/$@ >>$(LIBTOOL_LOG)
obj/libsam-static.la: $(OBJS)
$(STATUS) library '(static)'
libtool --mode=link gcc -static $(LDFLAGS) -o $@ $^ >>$(LIBTOOL_LOG)
obj/libsam.la: $(OBJS)
$(STATUS) library '(shared)'
libtool --mode=link gcc -rpath $(DESTDIR) $(LDFLAGS) -o $@ $^ >>$(LIBTOOL_LOG)
obj/%.lo: src/%.c
$(STATUS) compile $*
libtool --mode=compile gcc $(CFLAGS) -Iinc/ -c -o $@ $< >>$(LIBTOOL_LOG)
$(OBJS):|obj
obj:
$(STATUS) MKDIR $@
mkdir -p $@
.deps/%.d: src/%.c
$(STATUS) deps $*
gcc -Iinc/ -MM -MT obj/$*.o $< -o $@
-include $(DEPS)
DEPS+=.deps/finish
.deps/finish: lib/libsam.so
libtool --finish $(DESTDIR) >>$(LIBTOOL_LOG) && touch $@
$(DEPS):|.deps
.deps:
$(STATUS) MKDIR $@
mkdir -p $@
clean:
$(STATUS) clean
libtool --mode=clean rm -f obj/*.l* lib/*.l* lib/*.so* lib/*.a >>$(LIBTOOL_LOG)
rm -Rf .deps libtool.log
.PHONY: all cleanlog clean
\ No newline at end of file
#
# This Makefile contains instructions common to all platforms
#
#
# Build rules
#
all: clean depend libsam
depend:
$(CC) $(CFLAGS) -MM $(SRCDIR)/*.c > .depend
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(CFLAGS) -o $@ -c $<
libsam: $(OBJS)
$(AR) rcs $(LIBDIR)/libsam.a $(OBJS)
#
# Cleanup rules
#
clean:
-$(RM) -f $(LIBDIR)/libsam.a $(OBJDIR)/*.o .depend
#
# This Makefile is compatible with GNU Make and should work on Cygwin
#
#
# Your operating system
#
OS = CYGWIN
#
# Directories
#
INCDIR = inc
LIBDIR = lib
OBJDIR = obj
SRCDIR = src
#
# Programs
#
AR = ar
CC = gcc
RM = rm
#
# Flags
#
CFLAGS = -g -O2 -pipe -std=c99 -Wall
CFLAGS += -DOS=$(OS)
CFLAGS += -I$(INCDIR)
#
# Object files
#
OBJS = $(OBJDIR)/sam.o \
$(OBJDIR)/snprintf.o \
$(OBJDIR)/strl.o
#
# Include the make instructions common to all platforms
#
include Makefile.common
#
# This Makefile is compatible with GNU Make and should work on FreeBSD
#
#
# Your operating system
#
OS = FREEBSD
#
# Directories
#
INCDIR = inc
LIBDIR = lib
OBJDIR = obj
SRCDIR = src
#
# Programs
#
AR = ar
CC = gcc
RM = rm
#
# Flags
#
CFLAGS = -g -O2 -pipe -std=c99 -Wall
CFLAGS += -DOS=$(OS)
CFLAGS += -I$(INCDIR)
#
# Object files
#
OBJS = $(OBJDIR)/sam.o
#
# Include the make instructions common to all platforms
#
include Makefile.common
#
# This Makefile is compatible with GNU Make and should work on Linux
#
#
# Your operating system
#
OS = LINUX
#
# Directories
#
INCDIR = inc
LIBDIR = lib
OBJDIR = obj
SRCDIR = src
#
# Programs
#
AR = ar
CC = gcc
RM = rm
#
# Flags
#
CFLAGS = -g -O2 -pipe -std=c99 -Wall
CFLAGS += -DOS=$(OS)
CFLAGS += -I$(INCDIR)
#
# Object files
#
OBJS = $(OBJDIR)/sam.o \
$(OBJDIR)/strl.o
#
# Include the make instructions common to all platforms
#
include Makefile.common
#
# This Makefile is compatible with GNU Make and should work on Windows (MingW)
#
#
# Your operating system
#
OS = MINGW
#
# Directories
#
INCDIR = inc
LIBDIR = lib
OBJDIR = obj
SRCDIR = src
#
# Programs
#
AR = C:\MinGW\bin\ar
CC = C:\MinGW\bin\gcc
RM = C:\MinGW\bin\rm
#
# Flags
#
CFLAGS = -g -O2 -pipe -std=c99 -Wall
CFLAGS += -DOS=$(OS)
CFLAGS += -I$(INCDIR)
#
# Object files
#
OBJS = $(OBJDIR)/sam.o \
$(OBJDIR)/strl.o
#
# Include the make instructions common to all platforms
#
include Makefile.common
#
# This Makefile is compatible with GNU Make and should work on POSIX systems
#
FLAGS+=-g
#
# Programs
#
CFLAGS = $(FLAGS) -pipe -std=c99 -Wall
CFLAGS += -I../../inc
LDFLAGS = $(FLAGS) -L../../lib -lsam
CC = gcc
INSTALL = install
RM = rm
OBJS:=i2p-ping.lo
DEPS:=$(patsubst obj/%.lo, .deps/%.d, $(OBJS))
DESTDIR:=$(if $(DESTDIR),$(DESTDIR)/lib,/usr/lib)
#
# Flags
#
MAKEFLAGS=-s -r
PERL=$(shell which perl 2>/dev/null)
ifneq ($(PERL),)
STATUS=$(PERL) ../../status
else
STATUS=echo
endif
CFLAGS = -g -O2 -pipe -std=c99 -Wall
CFLAGS += -I../../inc -L../../lib
LIBS = -lsam
LIBTOOL_LOG=libtool.log
#
# Build rules
#
all:: cleanlog i2p-ping
all: clean i2p-ping
cleanlog:
>$(LIBTOOL_LOG)
i2p-ping: i2p-ping.c
$(CC) $(CFLAGS) -o i2p-ping.o -c i2p-ping.c
$(CC) $(CFLAGS) -o i2p-ping i2p-ping.o $(LIBS)
i2p-ping: $(OBJS)
$(STATUS) link
libtool --mode=link gcc $(LDFLAGS) -o $@ $^ >>$(LIBTOOL_LOG)
install: i2p-ping
$(INSTALL) i2p-ping $(HOME)/bin
#
# Cleanup rules
#
%.lo: %.c
$(STATUS) compile $*
libtool --mode=compile gcc $(CFLAGS) -Iinc/ -c -o $@ $< >>$(LIBTOOL_LOG)
.deps/%.d: src/%.c
$(STATUS) deps $*
gcc -Iinc/ -MM -MT obj/$*.o $^ -o $@
clean:
-$(RM) -f i2p-ping *.o
$(STATUS) clean
rm -Rf .deps obj libtool.log
libtool --mode=clean rm -f i2p-ping i2p-ping.lo >>$(LIBTOOL_LOG)
$(OBJS):|obj
obj:
$(STATUS) MKDIR $@
mkdir -p $@
-include $(DEPS)
$(DEPS):|.deps
.deps:
$(STATUS) MKDIR $@
mkdir -p $@
.PHONY: all cleanlog clean
\ No newline at end of file
#ifndef _PARSE_HEADER_FEEP
#define _PARSE_HEADER_FEEP
#include "tinystring.h"
typedef struct arg_s {
string_t name;
string_t value;
// int pos;
} arg_t;
typedef struct {
arg_t* arg;
int num;
} args_t;
args_t arg_parse(const char*);
void arg_done(args_t);
arg_t* arg_get(args_t,int);
arg_t* arg_find(args_t,string_t);
#define AG(a,b) arg_get(a,b)
#endif /* _PARSE_HEADER_FEEP */
......@@ -121,9 +121,9 @@ bool sam_read_buffer(sam_sess_t *session);
const char *sam_strerror(samerr_t code);
/* SAM controls - callbacks */
void (*sam_diedback)(sam_sess_t *session);
void (*sam_logback)(char *str);
void (*sam_namingback)(sam_sess_t *session, char *name,
sam_pubkey_t pubkey, samerr_t result);
void (*sam_logback)(const char *str);
void (*sam_namingback)(sam_sess_t *session, const char *name,
sam_pubkey_t pubkey, samerr_t result, const char* message);
/* Stream commands */
void sam_stream_close(sam_sess_t *session, sam_sid_t stream_id);
......@@ -131,14 +131,15 @@ sam_sid_t sam_stream_connect(sam_sess_t *session, const sam_pubkey_t dest);
samerr_t sam_stream_send(sam_sess_t *session, sam_sid_t stream_id,
const void *data, size_t size);
/* Stream commands - callbacks */
void (*sam_closeback)(sam_sess_t *session, sam_sid_t stream_id,
samerr_t reason);
void (*sam_closeback)(sam_sess_t *session, sam_sid_t stream_id,
samerr_t reason, const char* message);
void (*sam_connectback)(sam_sess_t *session, sam_sid_t stream_id,
sam_pubkey_t dest);
void (*sam_databack)(sam_sess_t *session, sam_sid_t stream_id,
sam_pubkey_t dest);
void (*sam_databack)(sam_sess_t *session, sam_sid_t stream_id,
void *data, size_t size);
void (*sam_statusback)(sam_sess_t *session, sam_sid_t stream_id,
samerr_t result);
void (*sam_statusback)(sam_sess_t *session, sam_sid_t stream_id,
samerr_t result, const char* message);
/* Stream send queue (experimental) */
void sam_sendq_add(sam_sess_t *session, sam_sid_t stream_id,
......
#ifndef TINYSTRING_HEADER
#define TINYSTRING_HEADER
#include <sys/types.h>
#ifndef bool
#define bool short int
#endif
struct string_s;
#define string_t struct string_s*
//Mysteeeerious *waggles mysteriously*
/*{
char* data;
long int size;
} *string_t;
*/
string_t string_create(const char*);
string_t string_ncreate(const char* cstr,long int length);
string_t string_wrap(const char*);
//Does not malloc, do NOT pass to string_free
string_t string_fmt(const char* fmt, ...);
string_t string_cat(string_t,string_t);
/* Source Dest */
void string_copy(string_t,string_t);
void string_copy_raw(string_t,void*,size_t);
const char* string_data(string_t);
long int string_size(string_t);
void string_free(string_t);
bool string_equal(string_t,string_t);
bool string_equali(string_t,string_t);
int string_cmp(string_t,string_t);
int string_cmpi(string_t,string_t);
#define _sw(a) string_wrap(a)
#define _scr(a,b,c) string_copy_raw(a,b,c)
#define string_is(a,b) (! strncmp(string_data(a),(b),string_size(a)))
#endif /* TINYSTRING_HEADER */
#include "parse.h"
#include <assert.h>
#include <ctype.h>
#include <malloc.h>
#define _GNU_SOURCE
#include <string.h>
args_t arg_parse(const char* line_raw) {
args_t self;
int numargs = 0;
const char *end, *last;
/* First pass to count how many args... */
end = line_raw;
while(*end && isspace(*end)) ++end;
//Skip initial space...
for(;;) {
while(*end && !isspace(*end)) ++end;
//Go to end of argument
++numargs;
while(*end && isspace(*end)) ++end;
//Go to end of space after argument
if(!*end) break;
}
self.num = numargs; // One more # args than spaces.
self.arg = malloc(sizeof(arg_t)*numargs);
/* Second pass to assign args. (Lemee alone, is more efficient than a linked list!) */
last = line_raw;
numargs = 0; //Now numargs is which current arg.
end = line_raw;
while(*end && isspace(*end)) ++end;
//Skip initial space...
for(;;) {
arg_t* nextarg = self.arg + numargs;;
const char* isbinary;
while(*end && !isspace(*end)) ++end;
//Go to end of argument
isbinary = strchr(last,'='); //Is there a value?
//Make sure not to pass end in our search for =
if(isbinary && (isbinary < end)) {
nextarg->name = string_ncreate(last,isbinary-last);
nextarg->value = string_ncreate(isbinary+1,end-isbinary-1);
} else {
nextarg->name = string_ncreate(last,end-last);
nextarg->value = string_create(NULL);
}
++numargs;
while(*end && isspace(*end)) ++end;
//Go to end of space after argument
if(!*end) break;
last = end;
}
return self;
}
void arg_done(args_t self) {
free(self.arg);
self.arg = NULL;
self.num = 0;
}
arg_t* arg_get(args_t self, int index) {
if(index >= self.num) return NULL;
return self.arg + index;
}
arg_t* arg_find(args_t self,string_t testname) {
int index;
for(index=0;index<self.num;++index) {
if(string_equali(self.arg[index].name,testname)) {
return self.arg + index;
}
}
return NULL;
}
......@@ -30,6 +30,10 @@
#include "sam.h"
#include "platform.h"
#include "parse.h"
#include "tinystring.h"
#include <assert.h>
static bool sam_hello(sam_sess_t *session);
static void sam_log(const char *format, ...);
......@@ -57,7 +61,7 @@ static ssize_t sam_write(sam_sess_t *session, const void *buf, size_t n);
*/
/* a peer closed the connection */
void (*sam_closeback)(sam_sess_t *session, sam_sid_t stream_id, samerr_t reason)
void (*sam_closeback)(sam_sess_t *session, sam_sid_t stream_id, samerr_t reason, const char* message)
= NULL;
/* a peer connected to us */
......@@ -76,15 +80,14 @@ void (*sam_dgramback)(sam_sess_t *session, sam_pubkey_t dest, void *data,
void (*sam_diedback)(sam_sess_t *session) = NULL;
/* logging callback */
void (*sam_logback)(char *str) = NULL;
void (*sam_logback)(const char *str) = NULL;
/* naming lookup reply - `pubkey' will be NULL if `result' isn't SAM_OK */
void (*sam_namingback)(sam_sess_t *session, char *name, sam_pubkey_t pubkey,
samerr_t result) = NULL;
void (*sam_namingback)(sam_sess_t *session, const char *name, sam_pubkey_t pubkey, samerr_t result, const char* message) = NULL;
/* our connection to a peer has completed */
void (*sam_statusback)(sam_sess_t *session, sam_sid_t stream_id,
samerr_t result) = NULL;
samerr_t result, const char* message) = NULL;
/* a peer sent some raw data (`data' MUST be freed) */
void (*sam_rawback)(sam_sess_t *session, void *data, size_t size) = NULL;
......@@ -290,13 +293,13 @@ static void sam_log(const char *format, ...)
*/
void sam_naming_lookup(sam_sess_t *session, const char *name)
{
assert(session != NULL);
char cmd[SAM_CMD_LEN];
assert(session != NULL);
char cmd[SAM_CMD_LEN];
snprintf(cmd, sizeof cmd, "NAMING LOOKUP NAME=%s\n", name);
sam_write(session, cmd, strlen(cmd));
snprintf(cmd, sizeof cmd, "NAMING LOOKUP NAME=%s\n", name);
sam_write(session, cmd, strlen(cmd));
return;
return;
}
/*
......@@ -304,241 +307,192 @@ void sam_naming_lookup(sam_sess_t *session, const char *name)
*
* s - string of data that we read (read past tense)
*/
bool sam_parse_args(sam_sess_t *session, args_t args);
static void sam_parse(sam_sess_t *session, char *s)
{
assert(session != NULL);
#define SAM_DGRAM_RECEIVED_REPLY "DATAGRAM RECEIVED"
#define SAM_NAMING_REPLY "NAMING REPLY"
#define SAM_NAMING_REPLY_OK "NAMING REPLY RESULT=OK"
#define SAM_NAMING_REPLY_IK "NAMING REPLY RESULT=INVALID_KEY"
#define SAM_NAMING_REPLY_KNF "NAMING REPLY RESULT=KEY_NOT_FOUND"
#define SAM_RAW_RECEIVED_REPLY "RAW RECEIVED"
#define SAM_STREAM_CLOSED_REPLY "STREAM CLOSED"
#define SAM_STREAM_CONNECTED_REPLY "STREAM CONNECTED"
#define SAM_STREAM_RECEIVED_REPLY "STREAM RECEIVED"
#define SAM_STREAM_STATUS_REPLY "STREAM STATUS"
#define SAM_STREAM_STATUS_REPLY_OK "STREAM STATUS RESULT=OK"
#define SAM_STREAM_STATUS_REPLY_CRP "STREAM STATUS RESULT=CANT_REACH_PEER"
#define SAM_STREAM_STATUS_REPLY_I2E "STREAM STATUS RESULT=I2P_ERROR"
#define SAM_STREAM_STATUS_REPLY_IK "STREAM STATUS RESULT=INVALID_KEY"
#define SAM_STREAM_STATUS_REPLY_TO "STREAM STATUS RESULT=TIMEOUT"
//Wrapper for ease of memory management
args_t args;
assert(session != NULL);
args = arg_parse(s);
if(!sam_parse_args(session, args)) {
SAMLOG("Unknown SAM command received: %s", s);
}
arg_done(args);
}
/*
* TODO: add raw parsing
*/
long int strtol_checked(const char* str) {
static char* end = NULL;
long int ret = strtol(str,&end,10);
assert(str != end || "No number found at all!");
return ret;
}
if (strncmp(s, SAM_DGRAM_RECEIVED_REPLY,
strlen(SAM_DGRAM_RECEIVED_REPLY)) == 0) {
char *p;
bool sam_parse_args(sam_sess_t *session, args_t args)
{
arg_t* arg; // The current argument being examined...
const char* message = NULL; // Almost EVERYTHING can have a message...
if(args.num <= 0) return 0;
#define ARG_IS(a,b) string_equal(AG(args,a)->name,string_wrap(b))
#define ARG_FIND(a) arg_find(args,_sw(a))
// Almost EVERYTHING can have a message...
arg = ARG_FIND("MESSAGE");
if(arg) {
message = string_data(arg->value);
}
if(ARG_IS(0,"DATAGRAM") &&
ARG_IS(1,"RECEIVED")) {
sam_pubkey_t dest;
size_t size;
void *data;
arg = ARG_FIND("DESTINATION");
assert(arg != NULL);
_scr(arg->value, dest, sizeof dest);
arg = ARG_FIND("SIZE");
assert(arg != NULL);
size = strtol_checked(string_data(arg->value));
data = malloc(size + 1);
/* +1 for NUL termination, so when we are
receiving a string it will just work and it
won't be necessary to send NUL. When binary
data is sent, the extra NUL character will
just be ignored by the client program,
because it is not added to the size */
if (data == NULL) {
SAMLOGS("Out of memory");
abort();
}
if (sam_read2(session, data, size) != -1) {
char* p = data + size;
*p = '\0'; /* see above NUL note */
sam_dgramback(session, dest, data, size); /* `data' must be freed */
} else
free(data);
} else if (ARG_IS(0,"NAMING") &&
ARG_IS(1, "REPLY")) {
if(NULL == (arg = ARG_FIND("RESULT"))) {
SAMLOGS("Naming reply with no result");
return 0;
}
if (string_is(arg->value,"OK")) {
sam_pubkey_t pubkey;
arg = ARG_FIND("VALUE");
assert(arg != NULL);
_scr(arg->value, pubkey, sizeof pubkey);
arg = ARG_FIND("NAME");
assert(arg != NULL);
sam_namingback(session, string_data(arg->value), pubkey, SAM_OK, message);
} else if(string_is(arg->value,"INVALID_KEY")) {
arg_t* namearg = ARG_FIND("NAME");
assert(namearg != NULL);
sam_namingback(session, string_data(namearg->value), NULL,
SAM_INVALID_KEY, message);
} else if(string_is(arg->value,"KEY_NOT_FOUND")) {
arg_t* namearg = ARG_FIND("NAME");
assert(namearg != NULL);
sam_namingback(session, string_data(namearg->value), NULL,
SAM_KEY_NOT_FOUND, message);
} else {
arg_t* namearg = ARG_FIND("NAME");
assert(namearg != NULL);
sam_namingback(session, string_data(namearg->value), NULL,
SAM_UNKNOWN, message);
}
} else if (ARG_IS(0,"STREAM")) {
sam_sid_t stream_id;
arg = ARG_FIND("ID");
assert(arg != 0);
stream_id = strtol_checked(string_data(arg->value));
if(ARG_IS(1,"CLOSED")) {
arg = ARG_FIND("RESULT");
assert(arg != NULL);
if (string_is(arg->value,"OK")) {
sam_closeback(session, stream_id, SAM_OK, message);
} else if (string_is(arg->value,"CANT_REACH_PEER")) {
sam_closeback(session, stream_id, SAM_CANT_REACH_PEER, message);
} else if (string_is(arg->value,"I2P_ERROR")) {
sam_closeback(session, stream_id, SAM_I2P_ERROR, message);
} else if (string_is(arg->value,"PEER_NOT_FOUND")) {
sam_closeback(session, stream_id, SAM_PEER_NOT_FOUND, message);
} else if (string_is(arg->value,"TIMEOUT")) {
sam_closeback(session, stream_id, SAM_TIMEOUT, message);
} else {
sam_closeback(session, stream_id, SAM_UNKNOWN, message);
}
} else if(ARG_IS(1,"CONNECTED")) {
sam_pubkey_t dest;
size_t size;
void *data;
p = strchr(s, '='); /* DESTINATION= */
assert(p != NULL);
p++;
strlcpy(dest, p, sizeof dest);
p = strchr(p, '='); /* SIZE= */
assert(p != NULL);
p++;
size = strtol(p, NULL, 10);
assert(size != 0);
data = malloc(size + 1); /* +1 for NUL termination, so when we are
receiving a string it will just work and it
won't be necessary to send NUL. When binary
data is sent, the extra NUL character will
just be ignored by the client program,
because it is not added to the size */
if (data == NULL) {
SAMLOGS("Out of memory");
abort();
}
if (sam_read2(session, data, size) != -1) {
p = data + size;
*p = '\0'; /* see above NUL note */
sam_dgramback(session, dest, data, size); /* `data' must be freed */
} else
free(data);
return;
} else if (strncmp(s, SAM_NAMING_REPLY, strlen(SAM_NAMING_REPLY)) == 0) {
char *p;
char *q;
char name[SAM_NAME_LEN];
p = strchr(s, '='); /* can't use strrchar because of option
MESSAGE= */
assert(p != NULL); /* RESULT= */
p++;
p = strchr(p, '='); /* NAME= */
assert(p != NULL);
p++;
arg = ARG_FIND("DESTINATION");
assert(arg != NULL);
_scr(arg->value, dest, sizeof dest);
if (strncmp(s, SAM_NAMING_REPLY_OK, strlen(SAM_NAMING_REPLY_OK)) == 0) {
sam_pubkey_t pubkey;
q = strchr(p, ' '); /* ' 'VAL.. */
assert(q != NULL);
*q = '\0';
q++;
q = strchr(q, '='); /* VALUE= */
assert(q != NULL);
q++;
strlcpy(name, p, sizeof name);
strlcpy(pubkey, q, sizeof pubkey);
sam_namingback(session, name, pubkey, SAM_OK);
} else if (strncmp(s, SAM_NAMING_REPLY_IK,
strlen(SAM_NAMING_REPLY_IK)) == 0) {
q = strchr(p, ' '); /* ' 'MES.. (optional) */
if (q != NULL)
*q = '\0';
strlcpy(name, p, sizeof name);
sam_namingback(session, name, NULL, SAM_INVALID_KEY);
} else if (strncmp(s, SAM_NAMING_REPLY_KNF,
strlen(SAM_NAMING_REPLY_KNF)) == 0) {
q = strchr(p, ' '); /* ' 'MES.. (optional) */
if (q != NULL)
*q = '\0';
strlcpy(name, p, sizeof name);
sam_namingback(session, name, NULL, SAM_KEY_NOT_FOUND);
} else {
q = strchr(p, ' '); /* ' 'MES.. (optional) */
if (q != NULL)
*q = '\0';
strlcpy(name, p, sizeof name);
sam_namingback(session, name, NULL, SAM_UNKNOWN);
}
return;
} else if (strncmp(s, SAM_STREAM_CLOSED_REPLY,
strlen(SAM_STREAM_CLOSED_REPLY)) == 0) {
char *p;
sam_sid_t stream_id;
p = strchr(s, '='); /* can't use strrchar because of option MESSAGE= */
assert(p != NULL); /* ID= */
p++;
stream_id = strtol(p, NULL, 10);
assert(stream_id != 0);
p = strchr(p, '='); /* RESULT= */
assert(p != NULL);
p++;
if (strncmp(p, "OK", strlen("OK")) == 0)
sam_closeback(session, stream_id, SAM_OK);
else if (strncmp(p, "CANT_REACH_PEER", strlen("CANT_REACH_PEER")) == 0)
sam_closeback(session, stream_id, SAM_CANT_REACH_PEER);
else if (strncmp(p, "I2P_ERROR", strlen("I2P_ERROR")) == 0)
sam_closeback(session, stream_id, SAM_I2P_ERROR);
else if (strncmp(p, "PEER_NOT_FOUND", strlen("PEER_NOT_FOUND")) == 0)
sam_closeback(session, stream_id, SAM_PEER_NOT_FOUND);
else if (strncmp(p, "TIMEOUT", strlen("TIMEOUT")) == 0)
sam_closeback(session, stream_id, SAM_TIMEOUT);
else
sam_closeback(session, stream_id, SAM_UNKNOWN);
return;
} else if (strncmp(s, SAM_STREAM_CONNECTED_REPLY,
strlen(SAM_STREAM_CONNECTED_REPLY)) == 0) {
char *p;
sam_sid_t stream_id;
sam_pubkey_t dest;
p = strrchr(s, '='); /* ID= */
assert(p != NULL);
*p = '\0';
p++;
stream_id = strtol(p, NULL, 10);
assert(stream_id != 0);
p = strstr(s, "N="); /* DESTINATION= */
p += 2;
strlcpy(dest, p, sizeof dest);
sam_connectback(session, stream_id, dest);
return;
} else if (strncmp(s, SAM_STREAM_RECEIVED_REPLY,
strlen(SAM_STREAM_RECEIVED_REPLY)) == 0) {
char *p;
sam_sid_t stream_id;
} else if(ARG_IS(1,"RECEIVED")) {
size_t size;
void *data;
p = strrchr(s, '='); /* SIZE= */
assert(p != NULL);
p++;
size = strtol(p, NULL, 10);
assert(size != 0);
p -= 6;
*p = '\0';
p = strrchr(s, '='); /* ID= */
assert(p != NULL);
p++;
stream_id = strtol(p, NULL, 10);
assert(stream_id != 0);
data = malloc(size + 1); /* +1 for NUL termination, so when we are
receiving a string it will just work and it
won't be necessary to send NUL. When binary
data is sent, the extra NUL character will
just be ignored by the client program,
because it is not added to the size */
arg = ARG_FIND("SIZE");
assert(arg != NULL);
size = strtol_checked(string_data(arg->value));
data = malloc(size + 1);
/* +1 for NUL termination, so when we are
receiving a string it will just work and it
won't be necessary to send NUL. When binary
data is sent, the extra NUL character will
just be ignored by the client program,
because it is not added to the size */
if (data == NULL) {
SAMLOGS("Out of memory");
abort();
}
if (sam_read2(session, data, size) != -1) {
p = data + size;
char* p = data + size;
*p = '\0'; /* see above NUL note */
sam_databack(session, stream_id, data, size);
/* ^^^ `data' must be freed ^^^*/
} else
free(data);
return;
} else if (strncmp(s, SAM_STREAM_STATUS_REPLY,
strlen(SAM_STREAM_STATUS_REPLY)) == 0) {
char *p;
sam_sid_t stream_id;
p = strchr(s, '='); /* can't use strrchar because of option MESSAGE= */
assert(p != NULL); /* RESULT= */
p++;
p = strchr(p, '='); /* ID= */
assert(p != NULL);
p++;
stream_id = strtol(p, NULL, 10);
assert(stream_id != 0);
if (strncmp(s, SAM_STREAM_STATUS_REPLY_OK,
strlen(SAM_STREAM_STATUS_REPLY_OK)) == 0)
sam_statusback(session, stream_id, SAM_OK);
else if (strncmp(s, SAM_STREAM_STATUS_REPLY_CRP,
strlen(SAM_STREAM_STATUS_REPLY_CRP)) == 0)
sam_statusback(session, stream_id, SAM_CANT_REACH_PEER);
else if (strncmp(s, SAM_STREAM_STATUS_REPLY_I2E,
strlen(SAM_STREAM_STATUS_REPLY_I2E)) == 0)
sam_statusback(session, stream_id, SAM_I2P_ERROR);
else if (strncmp(s, SAM_STREAM_STATUS_REPLY_IK,
strlen(SAM_STREAM_STATUS_REPLY_IK)) == 0)
sam_statusback(session, stream_id, SAM_INVALID_KEY);
else if (strncmp(s, SAM_STREAM_STATUS_REPLY_TO,
strlen(SAM_STREAM_STATUS_REPLY_TO)) == 0)
sam_statusback(session, stream_id, SAM_TIMEOUT);
else
sam_statusback(session, stream_id, SAM_UNKNOWN);
} else if(ARG_IS(1,"STATUS")) {
arg = ARG_FIND("RESULT");
assert(arg != NULL);
if (string_is(arg->value,"OK")) {
sam_statusback(session, stream_id, SAM_OK, message);
} else if (string_is(arg->value,"CANT_REACH_PEER")) {
sam_statusback(session, stream_id,
SAM_CANT_REACH_PEER, message);
} else if (string_is(arg->value,"I2P_ERROR")) {
sam_statusback(session, stream_id, SAM_I2P_ERROR, message);
} else if (string_is(arg->value,"INVALID_KEY")) {
sam_statusback(session, stream_id, SAM_INVALID_KEY, message);
} else if (string_is(arg->value,"TIMEOUT")) {
sam_statusback(session, stream_id, SAM_TIMEOUT, message);
} else {
sam_statusback(session, stream_id, SAM_UNKNOWN, message);
}
}
} else
return 0;
return -1;
}
return;
#undef ARG_IS
#undef ARG_FIND
} else
SAMLOG("Unknown SAM command received: %s", s);
return;
}
/*
* Sends data to a destination in a raw packet
......
#include "tinystring.h"
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <malloc.h>
#define _GNU_SOURCE
#include <string.h>
#ifndef min
#define min(a,b) ((a) > (b) ? (b) : (a))
#endif
extern char *strndup(const char *s, size_t n);
struct string_s {
const char* data;
long int size;
bool _no_del; //SIGH...
};
string_t string_ncreate(const char* cstr,long int length) {
string_t self = malloc(sizeof(struct string_s));
self->size = length;
if(cstr) self->data = strndup(cstr,length);
else self->data = NULL;
self->_no_del = 0;
return self;
}
string_t string_create(const char* cstr) {
if(!cstr)
return string_ncreate(NULL, 0);
return string_ncreate(cstr, strlen(cstr));
}
string_t string_nwrap(const char* cstr, long int length) {
static struct string_s self;
self.size = length;
self.data = cstr;
self._no_del = 1;
return &self;
}
string_t string_wrap(const char* cstr) {
if(!cstr)
return string_nwrap(NULL, 0);
return string_nwrap(cstr, strlen(cstr));
}
string_t string_fmt(const char* fmt, ...) {
va_list args;
FILE* tmp = tmpfile();
string_t self = malloc(sizeof(struct string_s));
char* data;
va_start(args, fmt);
vfprintf(tmp, fmt, args);
va_end(args);
self->size = ftell(tmp);
rewind(tmp);
data = malloc(self->size);
fread(data, self->size, sizeof(char), tmp);
fclose(tmp);
self->data = data;
return self;
}
string_t string_cat(string_t head,string_t tail) {
//There are two ways to skin a cat...
string_t self = malloc(sizeof(struct string_s));
char* data;
self->size = head->size+tail->size;
data = malloc(self->size);
memcpy(data, head->data, head->size);
memcpy(data+head->size,tail->data,tail->size);
self->data = data;
return self;
}
/* Source Dest */
void string_copy(string_t src,string_t dest) {
dest->data = realloc((char*)dest->data,src->size);
memcpy((char*)dest->data,src->data,dest->size);
}
void string_copy_raw(string_t src, void* dest,size_t size) {
size = min(src->size,size);
memcpy(dest,src->data,size);
}
const char* string_data(string_t self) {
return self->data;
}
long int string_size(string_t self) {
return self->size;
}
void string_free(string_t self) {
if(!self->_no_del)
free((char*)self->data);
free(self);
}
#ifndef min
#define min(a,b) ((a) < (b) ? (a) : (b))
#endif
bool string_equal(string_t this,string_t that) {
return !memcmp(this->data,that->data,min(this->size,that->size));
}
bool string_equali(string_t this,string_t that) {
return !strncasecmp(this->data,that->data,min(this->size,that->size));
}
int string_cmp(string_t this,string_t that) {
return memcmp(this->data,that->data,min(this->size,that->size));
}
int string_cmpi(string_t this,string_t that) {
return strncasecmp(this->data,that->data,min(this->size,that->size));
}
#!/usr/bin/env perl
printf "%-8s ",uc(shift @ARGV);
print join(' ', @ARGV),"\n";
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment