From 89da4c3668b31d52e409315edcab7f0ebc4db815 Mon Sep 17 00:00:00 2001 From: Avril Date: Tue, 14 May 2019 09:07:20 +0100 Subject: [PATCH] server can send responses --- Makefile | 3 + cl-sipc.asd | 2 +- cl-sipc.lisp | 63 +++++++++-- ffi.lisp | 65 ++++++++++- libsipc/Makefile | 2 +- libsipc/include/sipc.h | 27 ++++- libsipc/src/cli.c | 64 +++++++++-- libsipc/src/ffi.c | 23 ++++ libsipc/src/sipc.c | 249 ++++++++++++++++++++++++++++++++++++++--- test-server.lisp | 12 ++ 10 files changed, 466 insertions(+), 44 deletions(-) diff --git a/Makefile b/Makefile index 74042c0..61ec046 100644 --- a/Makefile +++ b/Makefile @@ -17,6 +17,9 @@ clean: install-ffi: if [[ $(shell id -u) == 0 ]]; then cp -f libsipc.so $(SYSTEM_INSTALL)/libsipc.so; fi +install-ffi-symbolic: + ln -sf "`pwd`/libsipc.so" $(SYSTEM_INSTALL)/libsipc.so + install: ffi install-ffi if [ -d "$(LOCAL_INSTALL)" ]; then sudo -u `logname` ln -nsi "`pwd`" "$(LOCAL_INSTALL)/cl-sipc"; fi diff --git a/cl-sipc.asd b/cl-sipc.asd index 980aa9f..d5f2e4e 100644 --- a/cl-sipc.asd +++ b/cl-sipc.asd @@ -4,7 +4,7 @@ :description "AF_UNIX IPC for CL" :author "Avril " :license "None" - :version "0.0.1" + :version "0.0.2" :serial t :depends-on ( :cffi ) :components ((:file "package") diff --git a/cl-sipc.lisp b/cl-sipc.lisp index a9a645e..3565a31 100644 --- a/cl-sipc.lisp +++ b/cl-sipc.lisp @@ -66,14 +66,18 @@ (release ,(first desc))) return-value)) -(defun %siqs-binary (sd value) - (cond ((pointer-p value) (siqs-binary sd (pointer-memory value) (pointer-size value))) - (t (with-pointer (ptr) value (%siqs-binary sd ptr))))) +(defun %siqs-binary-r (sd value flags resp) + (cond ((pointer-p value) (siqs-binary-r sd (pointer-memory value) (pointer-size value) flags resp )) + (t (with-pointer (ptr) value (%siqs-binary-r sd ptr flags resp ))))) -(defun send (sd value &optional (type :string)) +(defun %siqr-binary (sd value) + (cond ((pointer-p value) (siqr-binary sd (pointer-memory value) (pointer-size value))) + (t (with-pointer (ptr) value (%siqr-binary sd ptr))))) + +(defun send (sd value &optional (type :string) (keep-resp t)) "send to sever on socket sd. example: (with-bound-socket (socket \"file.socket\") (hook socket ...)) - returns (values t nil) on success. (values nil ) on failure. + returns (values response(t if none) nil) on success. (values nil ) on failure. error can be: :partial - Could not write whole message :error - send() error @@ -85,23 +89,60 @@ :binary - assumes `value' is either string or vector of bytes, send that as binary type :close - ignore value, send close signal " - (let ((rc (cond ((eql type :string) (siqs-string sd value)) - ((eql type :binary) (%siqs-binary sd value)) - ((eql type :close) (siqs-close sd)) + (let* ((response (sif-heap-alloc (if keep-resp 1 0))) + (rc (cond ((eql type :string) (siqs-string-r sd value 0 response)) + ((eql type :binary) (%siqs-binary-r sd value 0 response)) + ((eql type :close) (siqs-close-r sd 0 response)) (t :unknown-type)))) (if (numberp rc) (if (= rc #.+si-send-okay+) - (values t nil) - (values nil + (values + (if (null-pointer-p response) + t + (let ((resp (mem-ref response :pointer))) + (prog1 + (if (null-pointer-p resp) + t + (let ((resp-val nil)) + (si-typecase resp + :string #'(lambda (value) (setf resp-val value) + :binary #'(lambda (value) (setf resp-val value) + :close #'(lambda (value) (setf resp-val value))))) + resp-val)) + (sif-heap-free response)))) + nil) + (values (progn + (sif-heap-free response) + nil) (cond ((= rc #.+si-send-partial+) :partial) ((= rc #.+si-send-error+) :error) ((= rc #.+si-send-failure+) :failure) (t :unknown)))) rc))) +(defun respond (value &optional (type :string)) + (let ((sd (symbol-value '*response-message*))) + (if sd + (let ((rc (cond + ((eql type :string) (siqr-string sd value)) + ((eql type :binary) (%siqr-binary sd value)) + ((eql type :close) (siqr-close sd)) + (t :unknown-type)))) + (if (numberp rc) + (cond ((= rc #.+si-send-okay+) t) + ((= rc #.+sie-r-disable+) :response-disabled) + ((= rc #.+sie-r-multi+) :response-multi) + ((= rc #.+sie-r-invalid+) :response-invalid) + ((= rc #.+si-send-partial+) :partial) + ((= rc #.+si-send-error+) :error) + ((= rc #.+si-send-failure+) :failure) + (t :unknown)) + rc)) + :response-invalid))) + (defun send-quick (sock value &optional (type :string)) "Quickly send value to socket file `sock'" (with-bound-socket (sd sock :connect) (send sd value type))) -(mapc #'export '(connect send send-quick bind hook release with-bound-socket)) +(mapc #'export '(connect respond send send-quick bind hook release with-bound-socket)) diff --git a/ffi.lisp b/ffi.lisp index 7c57ab3..c84ecaa 100644 --- a/ffi.lisp +++ b/ffi.lisp @@ -2,7 +2,6 @@ (in-package :cl-sipc) - (defctype si-type :int) (defconstant +si-string+ 0) (defconstant +si-binary+ 1) @@ -13,6 +12,9 @@ (defconstant +sie-read+ 1) (defconstant +sie-pconcls+ 2) (defconstant +sie-invalid+ 3) +(defconstant +sie-r-invalid+ 4) +(defconstant +sie-r-multi+ 5) +(defconstant +sie-r-disable+ 6) (defctype si-send-rc :int) (defconstant +si-send-okay+ 0) @@ -20,6 +22,10 @@ (defconstant +si-send-error+ -1) (defconstant +si-send-failure+ -2) +;; params + +(defparameter *response-message* nil) + ;; library definition (define-foreign-library libsipc @@ -33,6 +39,8 @@ (defcfun "sif_type" si-type (message :pointer)) (defcfun "sif_size" :unsigned-int (message :pointer)) (defcfun "sif_data" :pointer (message :pointer)) +(defcfun "sif_heap_alloc" :pointer (keep-resp :int)) +(defcfun "sif_heap_free" :void (resp :pointer)) (defcfun "si_error_string" :pointer (err si-error)) @@ -50,9 +58,26 @@ (if (funcall (symbol-value '*on-error*) (marshal-ec err)) 0 1))) - -(defcallback si-callback :int ((message :pointer)) + +(defun si-typecase (message &key string binary close) (let* ((type (sif-type message)) + (size (sif-size message)) + (data (sif-data message)) + (rval (cond ((= type #.+si-string+) (funcall string (foreign-string-to-lisp data))) + ((= type #.+si-close+) (funcall close nil)) + ((= type #.+si-binary+) (funcall binary (make-pointer :memory data :size size)))))) + (if rval + 0 + 1))) + + +(defcallback si-callback :int ((message :pointer)) + (let ((*response-message* message)) + (si-typecase message + :string #'(lambda (value) (funcall (symbol-value '*on-message*) :string value)) + :binary #'(lambda (value) (funcall (symbol-value '*on-message*) :binary value)) + :close #'(lambda (avlue) (funcall (symbol-value '*on-message*) :close nil))))) +#| "(let* ((type (sif-type message)) (size (sif-size message)) (data (sif-data message)) (rval (cond ((= type #.+si-string+) (funcall (symbol-value '*on-message*) :string (foreign-string-to-lisp data))) @@ -60,7 +85,7 @@ ((= type #.+si-binary+) (funcall (symbol-value '*on-message*) :binary (make-pointer :memory data :size size)))))) (if rval 0 - 1))) + 1))))"|# ;; libsipc functions @@ -84,10 +109,42 @@ (sd :int) (string :string)) +(defcfun "siqs_string_r" :int + (sd :int) + (string :string) + (flags :unsigned-int) + (resp :pointer)) + (defcfun "siqs_close" :int (sd :int)) +(defcfun "siqs_close_r" :int + (sd :int) + (flags :unsigned-int) + (resp :pointer)) + (defcfun "siqs_binary" :int (sd :int) (buffer :pointer) (size :int)) + +(defcfun "siqs_binary_r" :int + (sd :int) + (buffer :pointer) + (size :int) + (flags :unsigned-int) + (resp :pointer)) + +(defcfun "siqr_string" :int + (sd :pointer) + (str :string)) + +(defcfun "siqr_binary" :int + (sd :pointer) + (str :pointer) + (size :int)) + +(defcfun "siqr_close" :int + (sd :pointer)) + + diff --git a/libsipc/Makefile b/libsipc/Makefile index 2064a00..7ea907e 100644 --- a/libsipc/Makefile +++ b/libsipc/Makefile @@ -1,7 +1,7 @@ TRANS:=src/sipc.c INCLUDE:=include/ STD:=gnu11 -CFLAGS:= --std=$(STD) -Wall -pedantic -I$(INCLUDE) +CFLAGS:= -g --std=$(STD) -Wall -pedantic -I$(INCLUDE) LCFLAGS:= -c $(CFLAGS) -fPIC all: clean libsipc sipcli diff --git a/libsipc/include/sipc.h b/libsipc/include/sipc.h index 4c1c5c3..5257c2a 100644 --- a/libsipc/include/sipc.h +++ b/libsipc/include/sipc.h @@ -21,8 +21,12 @@ typedef enum { _SI_ERROR, } si_type; +#define SI_NORESP (1<<0) +#define SI_DISCARD (1<<1) + typedef struct { si_type type; + unsigned int flags; unsigned int data_len; unsigned char data[]; } si_message; @@ -32,6 +36,10 @@ typedef enum { SIE_READ, //Sock read failure SIE_PCONCLS, //Sock closed before read complete SIE_INVALID, //Invalid message + + SIE_R_INVALID, //This message cannot be responded to like that + SIE_R_MULTI, //A response has already been sent + SIE_R_DISABLE, //The client asked to not be responded to } si_error; typedef int (*si_callback)(const si_message *msg); @@ -45,12 +53,23 @@ char* si_error_string(si_error err); char* si_type_string(si_type ty); int si_connect(const char* file); //Returns sd, or -1 on failure. +int si_sendmsg_r(int sd, const si_message* msg, si_message** response); //si_sendmmsg but optionally receive response (make sure to free() *response after you're done, NULL to discard response, if there is no response *response is not modified) int si_sendmsg(int sd, const si_message *msg); //Returns 0 on okay, 1 if whole message could not be sent, -1 on send error, -2 on weird send error. (see SI_SEND_*) //Quick funcs -int siqs_string(int sd, const char* string); //quick send string -int siqs_close(int sd); //quick send close -int siqs_binary(int sd, const unsigned char* buffer, size_t size); //quick send binary -int siqs_printf(int sd, const char* format, ...); //quick send string (printf format) +int siqs_string_r(int sd, const char* string, unsigned int flags, si_message** resp); //quick send string +int siqs_string(int sd, const char* string); //quick send string (discard response) +int siqs_close_r(int sd, unsigned int flags, si_message** resp); //quick send close +int siqs_close(int sd); //quick send close (discard response) +int siqs_binary_r(int sd, const unsigned char* buffer, size_t size, unsigned int flags, si_message** resp); //quick send binary +int siqs_binary(int sd, const unsigned char* buffer, size_t size); //quick send binary (discard response) + +int siqs_printf_r(int sd, unsigned int flags, si_message** resp, const char* format, ...); //quick send string (printf format) +#define siqs_printf(sd, ...) siqs_printf_r(sd, 0, NULL, __VA_ARGS__) //quick send string (printf format, discard response) + +int siqr_string(const si_message* sd, const char* string); //quick send response string +int siqr_binary(const si_message* sd, const unsigned char* bin, size_t size); //quick send response binary +int siqr_close (const si_message* sd); //quick send response close (kinda useless) +int siqr_printf(const si_message* sd, const char* fmt, ...); //quick send response string (printf format) #endif /* _LIBSIPC_H */ diff --git a/libsipc/src/cli.c b/libsipc/src/cli.c index 17735f5..af93784 100644 --- a/libsipc/src/cli.c +++ b/libsipc/src/cli.c @@ -34,6 +34,29 @@ char* strbin(const unsigned char* data, size_t sz) return buffer; } +int server_aresp =0; + +char* textmessage(const si_message *msg) +{ + char* text; + switch(msg->type) + { + case SI_CLOSE: + text = "..."; + break; + case SI_STRING: + text = (char*) msg->data; + break; + case SI_BINARY: + text = strbin(msg->data, (size_t)msg->data_len); + break; + default: + text= "(unbound)"; + break; + } + return text; +} + int on_message(const si_message *msg) { char* text; @@ -41,6 +64,15 @@ int on_message(const si_message *msg) int rc=0; + if(server_aresp) + { + int rc = siqr_printf(msg, "-> %s", textmessage(msg)); + if(rc==SI_SEND_OKAY) + ;//printf("[l] response send ok\n"); + else + printf("[e] %s\n", si_error_string((si_error)rc)); + } + switch(msg->type) { case SI_CLOSE: @@ -63,10 +95,12 @@ int on_message(const si_message *msg) return rc; } -int server(const char* bindto) +int server(const char* bindto, int secho) { int sd = si_bind(bindto); int rc=-1; + server_aresp = secho; + if(sd<0) { printf("error binding\n"); } else { @@ -119,7 +153,12 @@ int client(const char* conto, const char* string, int bin) if(sd<0) { printf("connect error\n"); } else { - int rrc = si_sendmsg(sd, msg); + si_message *response = NULL; + int rrc = si_sendmsg_r(sd, msg, &response); + if(response) { + printf(" <- (%s) %s\n", si_type_string(response->type), textmessage(response)); + free(response); + } rc = cli_return(rrc); si_close(sd); } @@ -141,8 +180,13 @@ int client_close(const char* conto) if(sd<0) { printf("connect error\n"); } else { - int rrc = si_sendmsg(sd, msg); - rc = cli_return(rrc); + si_message* response = NULL; + int rrc = si_sendmsg_r(sd, msg, &response); + if(response) { + printf(" <- (%s) %s\n", si_type_string(response->type), textmessage(response)); + free(response); + } + rc = cli_return(rrc); si_close(sd); } @@ -152,15 +196,19 @@ int client_close(const char* conto) int main(int argc, char** argv) { - int rc=0; + int rc=0,secho=0; if(argv[1] && argv[2] && argv[1][0]=='-') { switch(argv[1][1]) { case 'l': //Listen + if(argv[1][2] == 'f') unlink(argv[2]); - rc = server(argv[2]); + secho = (argv[1][2] == 'e' || + (argv[1][2] && argv[1][3] == 'e')); + + rc = server(argv[2], secho); break; case 'p': //Write @@ -188,8 +236,8 @@ int main(int argc, char** argv) } } else { - printf("usage: %s -l[f] \nusage: %s -p[b] \nusage: %s -c[f] \n", argv[0], argv[0], argv[0]); - printf("\n-l[f]\tlisten on socket. (f to unlink file first)\n"); + printf("usage: %s -l[fe] \nusage: %s -p[b] \nusage: %s -c[f] \n", argv[0], argv[0], argv[0]); + printf("\n-l[fe]\tlisten on socket. (f to unlink file first, e to send response)\n"); printf("-p[b]\twrite to socket. (b to send as binary)\n"); printf("-c[f]\tsend cose signal to socket. (f to unlink file after)\n"); } diff --git a/libsipc/src/ffi.c b/libsipc/src/ffi.c index dbe3b2c..2f6c031 100644 --- a/libsipc/src/ffi.c +++ b/libsipc/src/ffi.c @@ -1,4 +1,5 @@ #include +#include //Some FFI helpers @@ -16,3 +17,25 @@ const unsigned char* sif_data(const si_message* msg) { return msg->data; } + +si_message** sif_heap_alloc(int keepresp) +{ + if(keepresp) + { + si_message **resp = malloc(sizeof(si_message*)); + *resp = NULL; + return resp; + } + else return NULL; +} + +void sif_heap_free(si_message **msg) +{ + if(msg) { + if(*msg) { + free(*msg); + *msg = NULL; + } + free(msg); + } +} diff --git a/libsipc/src/sipc.c b/libsipc/src/sipc.c index 37f0ca0..5f033e2 100644 --- a/libsipc/src/sipc.c +++ b/libsipc/src/sipc.c @@ -9,6 +9,13 @@ #include +#define _SIRH_CHECK 0xabad +struct si_response_header { + unsigned short check; + int sd; + int resp_sent; +}; + int si_bind(const char* file) { int sd, rc; @@ -45,6 +52,8 @@ static int _si_read_rest(int sd, si_message *message) int read = 0; int rd=0; + if(message->data_len<1) return 0; + while( (read += (rd = recv(sd, message->data, message->data_len, 0))) < message->data_len) { if(rd<0) return -1; @@ -95,10 +104,16 @@ int si_listen(int sd, si_error_callback on_error, si_callback on_message) si_message *full; if(_si_valid_header(message)) { - full = malloc(sizeof(si_message)+message->data_len+1); - memset(full,0,sizeof(si_message)+message->data_len+1); //always have null-term + struct si_response_header* full0 = malloc(sizeof(si_message)+message->data_len+1+sizeof(struct si_response_header)); + memset(full0,0,sizeof(si_message)+message->data_len+1+sizeof(struct si_response_header)); //always have null-term + full0->check = _SIRH_CHECK; + full0->sd = csd; + + full = (si_message*)(((unsigned char*)full0)+sizeof(struct si_response_header)); memcpy(full, message, sizeof(si_message)); + rc = _si_read_rest(csd, full); + if(rc!=0) { if(rc==-1) rc = on_error(SIE_READ); @@ -106,14 +121,32 @@ int si_listen(int sd, si_error_callback on_error, si_callback on_message) rc = on_error(SIE_PCONCLS); if(rc<0) { close(csd); + free(full0); break; } } else { //Message has been read. - rc = on_message(full); - free(full); + + rc = (full->flags & SI_DISCARD) ? 0 : on_message(full); + + if(!full0->resp_sent && !(full->flags & SI_NORESP)) + { + //Send blank response. (Unless client asked for none.) + si_message *resp = malloc(sizeof(si_message)); + resp->type = SI_BINARY; + resp->flags = SI_DISCARD | SI_NORESP; + resp->data_len = 0; + int rc2 = si_sendmsg(csd, resp); + + if (rc2 != SI_SEND_OKAY) + rc = on_error((si_error)rc2); + + free(resp); + + } } + free(full0); } else { rc = on_error(SIE_INVALID); @@ -147,6 +180,16 @@ char *si_error_string(si_error err) break; case SIE_INVALID: put("SIE_INVALID: Bad message"); + break; + case SIE_R_INVALID: + puts("SIE_R_INVALID: Cannot respond to this"); + break; + case SIE_R_MULTI: + puts("SIE_R_MULTI: A response has already been sent"); + break; + case SIE_R_DISABLE: + puts("SIE_R_DISABLE: A response is not expected"); + break; default: put("SIE_UNKNOWN: Unknown EC %d", (int)err); break; @@ -202,7 +245,54 @@ int si_connect(const char *file) return sd; } -int si_sendmsg(int sd, const si_message *msg) +int si_read_response(int sd, si_message** resp) +{ + unsigned char buffer[sizeof(si_message)]; + si_message* head = (si_message*)buffer; + + int rc=0; + int read,rd; + read=rd=0; + + memset(buffer,0,sizeof(si_message)); + + while( (read += (rd = recv(sd, buffer, sizeof(si_message), 0))) < sizeof(si_message)) + { + if(rd<0) + { + rc = (int)SIE_READ; + break; + } else if(rd==0) + { + rc = (int)SIE_PCONCLS; + break; + } + } + if(rc==0) + { + si_message *full = malloc(sizeof(si_message)+head->data_len+1); + memset(full,0,sizeof(si_message)+head->data_len+1); + memcpy(full, head, sizeof(si_message)); + rc = _si_read_rest(sd, full); + switch(rc) { + case 0: + if(full->flags & SI_DISCARD) + free(full); + else + *resp = full; + return 0; + case -1: + free(full); + return (int)SIE_READ; + case -2: + free(full); + return (int)SIE_PCONCLS; + } + } + return rc; +} + +static int _si_sendmsg(int sd, const si_message* msg) { int rc = send(sd, msg, sizeof(si_message)+msg->data_len, 0); if(rc<0) @@ -215,40 +305,155 @@ int si_sendmsg(int sd, const si_message *msg) return SI_SEND_OKAY; } +int si_sendmsg_r(int sd, const si_message *msg, si_message** resp) +{ + int rc = _si_sendmsg(sd, msg); + + if(!(msg->flags & SI_NORESP)) + { + si_message* _resp=NULL; + rc = si_read_response(sd, &_resp); + if(resp && _resp && !(_resp->flags & SI_DISCARD) && rc==0) + { + //printf("setting resp\n"); + *resp = _resp; + } + else { + //printf("not setting %d %d %d %d\n", !!resp, !!_resp, _resp && (_resp->flags & SI_DISCARD), rc); + if(_resp) + free(_resp); + } + return rc==0?SI_SEND_OKAY:rc; + } + + return SI_SEND_OKAY; +} + +int si_sendmsg(int sd, const si_message *msg) +{ + return si_sendmsg_r(sd,msg,NULL); +} + +int si_response(const si_message *to, const si_message *msg) +{ + struct si_response_header *rhead = (struct si_response_header*)(((intptr_t)to)-sizeof(struct si_response_header)); + if(rhead->check != _SIRH_CHECK) + return (int)SIE_R_INVALID; + + if(rhead->resp_sent) + return (int)SIE_R_MULTI; + + if(rhead->resp_sent) + return (int)SIE_R_DISABLE; + + int rc = _si_sendmsg(rhead->sd, msg); + + rhead->resp_sent = 1; + + return rc; +} + //Quick send functions -int siqs_string(int sd, const char* string) +int siqs_string_r(int sd, const char* string, unsigned int flags, si_message** resp) { - si_message *msg = malloc(sizeof(si_message)+strlen(string)); - memset(msg,0,sizeof(si_message)+strlen(string)); + si_message *msg = malloc(sizeof(si_message)+strlen(string)+1); + memset(msg,0,sizeof(si_message)+strlen(string)+1); msg->type = SI_STRING; - msg->data_len = strlen(string); + msg->data_len = strlen(string)+1; + msg->flags = flags; memcpy(msg->data, string, msg->data_len); - int rc = si_sendmsg(sd, msg); + int rc = si_sendmsg_r(sd, msg, resp); free(msg); return rc; } +int siqs_string(int sd, const char* string) +{ + return siqs_string_r(sd, string, 0, NULL); +} -int siqs_close(int sd) +int siqs_close_r(int sd, unsigned int flags, si_message** resp) { si_message *msg = malloc(sizeof(si_message)); memset(msg,0,sizeof(si_message)); msg->type = SI_CLOSE; msg->data_len=0; + msg->flags = flags; - int rc = si_sendmsg(sd, msg); + int rc = si_sendmsg_r(sd, msg, resp); free(msg); return rc; } +int siqs_close(int sd) +{ + return siqs_close_r(sd, 0, NULL); +} + +int siqs_binary_r(int sd, const unsigned char* buffer, size_t size, unsigned int flags, si_message** resp) +{ + si_message *msg = malloc(sizeof(si_message)+size); + memset(msg,0,sizeof(si_message)+size); + msg->type = SI_BINARY; + msg->data_len = size; + msg->flags = flags; + + memcpy(msg->data, buffer, msg->data_len); + + int rc = si_sendmsg_r(sd, msg, resp); + + free(msg); + return rc; +} int siqs_binary(int sd, const unsigned char* buffer, size_t size) +{ + return siqs_binary_r(sd,buffer,size,0,NULL); +} + +// -- + +int siqs_printf_r(int sd, unsigned int flags, si_message** resp, const char* format, ...) +{ + char buffer[SIQ_PRINTF_BUFFER_SIZE]; + va_list list; + va_start(list, format); + memset(buffer,0,SIQ_PRINTF_BUFFER_SIZE); + + vsnprintf(buffer, SIQ_PRINTF_BUFFER_SIZE-1, format, list); + + int rc = siqs_string_r(sd, buffer, flags,resp); + + va_end(list); + + return rc; +} + +//Quick resp funcs + +int siqr_string(const si_message* sd, const char* string) +{ + si_message *msg = malloc(sizeof(si_message)+strlen(string)+1); + memset(msg,0,sizeof(si_message)+strlen(string)+1); + + msg->type = SI_STRING; + msg->data_len = strlen(string)+1; + + memcpy(msg->data, string, msg->data_len); + + int rc = si_response(sd, msg); + + free(msg); + return rc; +} + +int siqr_binary(const si_message* sd, const unsigned char* buffer, size_t size) { si_message *msg = malloc(sizeof(si_message)+size); memset(msg,0,sizeof(si_message)+size); @@ -258,13 +463,27 @@ int siqs_binary(int sd, const unsigned char* buffer, size_t size) memcpy(msg->data, buffer, msg->data_len); - int rc = si_sendmsg(sd, msg); + int rc = si_response(sd, msg); + + free(msg); + return rc; +} + +int siqr_close(const si_message* sd) +{ + si_message *msg = malloc(sizeof(si_message)); + memset(msg,0,sizeof(si_message)); + + msg->type = SI_CLOSE; + msg->data_len = 0; + + int rc = si_response(sd, msg); free(msg); return rc; } -int siqs_printf(int sd, const char* format, ...) +int siqr_printf(const si_message* sd, const char* format, ...) { char buffer[SIQ_PRINTF_BUFFER_SIZE]; va_list list; @@ -273,7 +492,7 @@ int siqs_printf(int sd, const char* format, ...) vsnprintf(buffer, SIQ_PRINTF_BUFFER_SIZE-1, format, list); - int rc = siqs_string(sd, buffer); + int rc = siqr_string(sd, buffer); va_end(list); diff --git a/test-server.lisp b/test-server.lisp index 4262844..74e142d 100644 --- a/test-server.lisp +++ b/test-server.lisp @@ -4,6 +4,11 @@ (ql:quickload :cl-sipc)) (defparameter *socket-file* "sipc.socket") +(defparameter *respond* t) + +(when (probe-file *socket-file*) + (delete-file *socket-file*)) + (defparameter *socket* (cl-sipc:bind *socket-file*)) ;;attempt to bind to this file (when (not *socket*) @@ -17,6 +22,13 @@ (format t "Error: ~a~%" err) nil) ;;returning NIL to the listener stops #'(lambda (type message) ;; Callback ran when a message is received + (when *respond* + (format t + " -> ~a~%" + (sipc:respond + (if (eql type :binary) + (format nil "~a" (sipc:pointer-to-array message)) + (format nil "~a" message))))) (if (eql type :binary) (format t " <- (~a) ~a (size: ~a)~%" type (sipc:pointer-to-array message) (sipc:pointer-size message)) ;;print the binary message as an array of bytes, the type, & the size (format t " <- (~a) ~a~%" type message)) ;;print the message & type