From c59df870c2fdb62d57589eac8c1e09a643a156d5 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Sat, 20 Mar 2004 22:45:16 +0000 Subject: added syslog-style debug message levels svn path=/trunk/externals/maxlib/; revision=1458 --- src/netserver.c | 953 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 520 insertions(+), 433 deletions(-) diff --git a/src/netserver.c b/src/netserver.c index 1141cb9..90ccb39 100644 --- a/src/netserver.c +++ b/src/netserver.c @@ -56,8 +56,20 @@ #define MAX_CONNECT 32 /* maximum number of connections */ #define INBUFSIZE 4096 /* size of receiving data buffer */ -static char *version = "netserver v0.2 :: bidirectional communication for Pd\n" - " written by Olaf Matthes "; +/* message levels from syslog.h */ +#define LOG_EMERG 0 /* system is unusable */ +#define LOG_ALERT 1 /* action must be taken immediately */ +#define LOG_CRIT 2 /* critical conditions */ +#define LOG_ERR 3 /* error conditions */ +#define LOG_WARNING 4 /* warning conditions */ +#define LOG_NOTICE 5 /* normal but significant condition */ +#define LOG_INFO 6 /* informational */ +#define LOG_DEBUG 7 /* debug-level messages */ + +static char *version = + "netserver v0.2.hcs1 :: bidirectional communication for Pd\n" + " written by Olaf Matthes \n" + " syslogging by Hans-Christoph Steiner "; /* ----------------------------- netserver ------------------------- */ @@ -69,119 +81,123 @@ typedef void (*t_netserver_socketreceivefn)(void *x, t_binbuf *b); typedef struct _netserver { - t_object x_obj; - t_outlet *x_msgout; - t_outlet *x_connectout; - t_outlet *x_clientno; - t_outlet *x_connectionip; - t_symbol *x_host[MAX_CONNECT]; - t_int x_fd[MAX_CONNECT]; - t_int x_sock_fd; - t_int x_connectsocket; - t_int x_nconnections; + t_object x_obj; + t_outlet *x_msgout; + t_outlet *x_connectout; + t_outlet *x_clientno; + t_outlet *x_connectionip; + t_symbol *x_host[MAX_CONNECT]; + t_int x_fd[MAX_CONNECT]; + t_int x_sock_fd; + t_int x_connectsocket; + t_int x_nconnections; +/* for syslog style logging priorities */ + t_int x_log_pri; } t_netserver; typedef struct _netserver_socketreceiver { - char *sr_inbuf; - int sr_inhead; - int sr_intail; - void *sr_owner; - t_netserver_socketnotifier sr_notifier; - t_netserver_socketreceivefn sr_socketreceivefn; + char *sr_inbuf; + int sr_inhead; + int sr_intail; + void *sr_owner; + t_netserver_socketnotifier sr_notifier; + t_netserver_socketreceivefn sr_socketreceivefn; } t_netserver_socketreceiver; static t_netserver_socketreceiver *netserver_socketreceiver_new(void *owner, t_netserver_socketnotifier notifier, - t_netserver_socketreceivefn socketreceivefn) + t_netserver_socketreceivefn socketreceivefn) { - t_netserver_socketreceiver *x = (t_netserver_socketreceiver *)getbytes(sizeof(*x)); - x->sr_inhead = x->sr_intail = 0; - x->sr_owner = owner; - x->sr_notifier = notifier; - x->sr_socketreceivefn = socketreceivefn; - if (!(x->sr_inbuf = malloc(INBUFSIZE))) bug("t_netserver_socketreceiver"); - return (x); + t_netserver_socketreceiver *x = (t_netserver_socketreceiver *)getbytes(sizeof(*x)); + x->sr_inhead = x->sr_intail = 0; + x->sr_owner = owner; + x->sr_notifier = notifier; + x->sr_socketreceivefn = socketreceivefn; + if (!(x->sr_inbuf = malloc(INBUFSIZE))) bug("t_netserver_socketreceiver"); + return (x); } - /* this is in a separately called subroutine so that the buffer isn't - sitting on the stack while the messages are getting passed. */ +/* this is in a separately called subroutine so that the buffer isn't + sitting on the stack while the messages are getting passed. */ static int netserver_socketreceiver_doread(t_netserver_socketreceiver *x) { - char messbuf[INBUFSIZE], *bp = messbuf; - int indx; - int inhead = x->sr_inhead; - int intail = x->sr_intail; - char *inbuf = x->sr_inbuf; - if (intail == inhead) return (0); - for (indx = intail; indx != inhead; indx = (indx+1)&(INBUFSIZE-1)) - { - char c = *bp++ = inbuf[indx]; - if (c == ';' && (!indx || inbuf[indx-1] != '\\')) - { - intail = (indx+1)&(INBUFSIZE-1); - binbuf_text(inbinbuf, messbuf, bp - messbuf); - x->sr_inhead = inhead; - x->sr_intail = intail; - return (1); - } - } - return (0); + char messbuf[INBUFSIZE], *bp = messbuf; + int indx; + int inhead = x->sr_inhead; + int intail = x->sr_intail; + char *inbuf = x->sr_inbuf; + if (intail == inhead) return (0); + for (indx = intail; indx != inhead; indx = (indx+1)&(INBUFSIZE-1)) + { + char c = *bp++ = inbuf[indx]; + if (c == ';' && (!indx || inbuf[indx-1] != '\\')) + { + intail = (indx+1)&(INBUFSIZE-1); + binbuf_text(inbinbuf, messbuf, bp - messbuf); + x->sr_inhead = inhead; + x->sr_intail = intail; + return (1); + } + } + return (0); } static void netserver_socketreceiver_read(t_netserver_socketreceiver *x, int fd) { - char *semi; - int readto = (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1); - int ret; - - t_netserver *y = x->sr_owner; - - y->x_sock_fd = fd; - - /* the input buffer might be full. If so, drop the whole thing */ - if (readto == x->sr_inhead) - { - post("netserver: dropped message"); - x->sr_inhead = x->sr_intail = 0; - readto = INBUFSIZE; - } - else - { - ret = recv(fd, x->sr_inbuf + x->sr_inhead, - readto - x->sr_inhead, 0); - if (ret < 0) - { - sys_sockerror("recv"); - if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner); - sys_rmpollfn(fd); - sys_closesocket(fd); - } - else if (ret == 0) - { - post("netserver: << connection closed on socket %d", fd); - if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner); - sys_rmpollfn(fd); - sys_closesocket(fd); - } - else - { - x->sr_inhead += ret; - if (x->sr_inhead >= INBUFSIZE) x->sr_inhead = 0; - while (netserver_socketreceiver_doread(x)) - { - outlet_setstacklim(); - if (x->sr_socketreceivefn) - (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf); - else binbuf_eval(inbinbuf, 0, 0, 0); - } - } - } + char *semi; + int readto = (x->sr_inhead >= x->sr_intail ? INBUFSIZE : x->sr_intail-1); + int ret; + + t_netserver *y = x->sr_owner; + + y->x_sock_fd = fd; + + /* the input buffer might be full. If so, drop the whole thing */ + if (readto == x->sr_inhead) + { + if (y->x_log_pri >= LOG_ERR) + post("netserver: dropped message"); + x->sr_inhead = x->sr_intail = 0; + readto = INBUFSIZE; + } + else + { + ret = recv(fd, x->sr_inbuf + x->sr_inhead, + readto - x->sr_inhead, 0); + if (ret < 0) + { + sys_sockerror("recv"); + if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner); + sys_rmpollfn(fd); + sys_closesocket(fd); + } + else if (ret == 0) + { + if (y->x_log_pri >= LOG_NOTICE) + post("netserver: << connection closed on socket %d", fd); + if (x->sr_notifier) (*x->sr_notifier)(x->sr_owner); + sys_rmpollfn(fd); + sys_closesocket(fd); + } + else + { + x->sr_inhead += ret; + if (x->sr_inhead >= INBUFSIZE) x->sr_inhead = 0; + while (netserver_socketreceiver_doread(x)) + { + outlet_setstacklim(); + if (x->sr_socketreceivefn) + (*x->sr_socketreceivefn)(x->sr_owner, inbinbuf); + else binbuf_eval(inbinbuf, 0, 0, 0); + } + } + } } static void netserver_socketreceiver_free(t_netserver_socketreceiver *x) { - free(x->sr_inbuf); - freebytes(x, sizeof(*x)); + free(x->sr_inbuf); + freebytes(x, sizeof(*x)); } /* ---------------- main netserver (send) stuff --------------------- */ @@ -189,185 +205,204 @@ static void netserver_socketreceiver_free(t_netserver_socketreceiver *x) /* send message to client using socket number */ static void netserver_send(t_netserver *x, t_symbol *s, int argc, t_atom *argv) { - int sockfd, client = -1, i; - if(x->x_nconnections < 0) - { - post("netserver: no clients connected"); - return; - } - if(argc < 2) - { - post("netserver: nothing to send"); - return; - } - /* get socket number of connection (first element in list) */ - if(argv[0].a_type == A_FLOAT) - { - sockfd = atom_getfloatarg(0, argc, argv); - for(i = 0; i < x->x_nconnections; i++) /* check if connection exists */ - { - if(x->x_fd[i] == sockfd) + int sockfd, client = -1, i; + if(x->x_nconnections < 0) + { + if (x->x_log_pri >= LOG_WARNING) + post("netserver: no clients connected"); + return; + } + if(argc < 2) + { + if (x->x_log_pri >= LOG_WARNING) + post("netserver: nothing to send"); + return; + } + /* get socket number of connection (first element in list) */ + if(argv[0].a_type == A_FLOAT) + { + sockfd = atom_getfloatarg(0, argc, argv); + for(i = 0; i < x->x_nconnections; i++) /* check if connection exists */ + { + if(x->x_fd[i] == sockfd) + { + client = i; /* the client we're sending to */ + break; + } + } + if(client == -1) + { + if (x->x_log_pri >= LOG_CRIT) + post("netserver: no connection on socket %d", sockfd); + return; + } + } + else + { + if (x->x_log_pri >= LOG_CRIT) + post("netserver: no socket specified"); + return; + } + /* process & send data */ + if(sockfd > 0) + { + t_binbuf *b = binbuf_new(); + char *buf, *bp; + int length, sent; + t_atom at; + binbuf_add(b, argc - 1, argv + 1); /* skip first element */ + SETSEMI(&at); + binbuf_add(b, 1, &at); + binbuf_gettext(b, &buf, &length); + + if (x->x_log_pri >= LOG_DEBUG) + { + post("netserver: sending data to client %d on socket %d", client + 1, sockfd); + post("netserver: sending \"%s\"", buf); + } + + for (bp = buf, sent = 0; sent < length;) + { + static double lastwarntime; + static double pleasewarn; + double timebefore = clock_getlogicaltime(); + int res = send(sockfd, buf, length-sent, 0); + double timeafter = clock_getlogicaltime(); + int late = (timeafter - timebefore > 0.005); + if (late || pleasewarn) + { + if (timeafter > lastwarntime + 2) { - client = i; /* the client we're sending to */ - break; + if (x->x_log_pri >= LOG_WARNING) + post("netserver blocked %d msec", + (int)(1000 * ((timeafter - timebefore) + pleasewarn))); + pleasewarn = 0; + lastwarntime = timeafter; } - } - if(client == -1) - { - post("netserver: no connection on socket %d", sockfd); - return; - } - } - else - { - post("netserver: no socket specified"); - return; - } - /* process & send data */ - if(sockfd > 0) - { - t_binbuf *b = binbuf_new(); - char *buf, *bp; - int length, sent; - t_atom at; - binbuf_add(b, argc - 1, argv + 1); /* skip first element */ - SETSEMI(&at); - binbuf_add(b, 1, &at); - binbuf_gettext(b, &buf, &length); - - post("netserver: sending data to client %d on socket %d", client + 1, sockfd); - // post("netserver: sending \"%s\"", buf); - - for (bp = buf, sent = 0; sent < length;) - { - static double lastwarntime; - static double pleasewarn; - double timebefore = clock_getlogicaltime(); - int res = send(sockfd, buf, length-sent, 0); - double timeafter = clock_getlogicaltime(); - int late = (timeafter - timebefore > 0.005); - if (late || pleasewarn) - { - if (timeafter > lastwarntime + 2) - { - post("netserver blocked %d msec", - (int)(1000 * ((timeafter - timebefore) + pleasewarn))); - pleasewarn = 0; - lastwarntime = timeafter; - } - else if (late) pleasewarn += timeafter - timebefore; - } - if (res <= 0) - { - sys_sockerror("netserver"); - post("netserver: could not send data to client"); - break; - } - else - { - sent += res; - bp += res; - } - } - t_freebytes(buf, length); - binbuf_free(b); - } - else post("netserver: not a valid socket number (%d)", sockfd); + else if (late) pleasewarn += timeafter - timebefore; + } + if (res <= 0) + { + sys_sockerror("netserver"); + if (x->x_log_pri >= LOG_ERR) + post("netserver: could not send data to client"); + break; + } + else + { + sent += res; + bp += res; + } + } + t_freebytes(buf, length); + binbuf_free(b); + } + else if (x->x_log_pri >= LOG_CRIT) + post("netserver: not a valid socket number (%d)", sockfd); } /* send message to client using client number note that the client numbers might change in case a client disconnects! */ static void netserver_client_send(t_netserver *x, t_symbol *s, int argc, t_atom *argv) { - int sockfd, client; - if(x->x_nconnections < 0) - { - post("netserver: no clients connected"); - return; - } - if(argc < 2) - { - post("netserver: nothing to send"); - return; - } - /* get number of client (first element in list) */ - if(argv[0].a_type == A_FLOAT) - client = atom_getfloatarg(0, argc, argv); - else - { - post("netserver: no client specified"); - return; - } - sockfd = x->x_fd[client - 1]; /* get socket number for that client */ - - /* process & send data */ - if(sockfd > 0) - { - t_binbuf *b = binbuf_new(); - char *buf, *bp; - int length, sent; - t_atom at; - binbuf_add(b, argc - 1, argv + 1); /* skip first element */ - SETSEMI(&at); - binbuf_add(b, 1, &at); - binbuf_gettext(b, &buf, &length); - - post("netserver: sending data to client %d on socket %d", client, sockfd); - // post("netserver: >> sending \"%s\"", buf); - - for (bp = buf, sent = 0; sent < length;) - { - static double lastwarntime; - static double pleasewarn; - double timebefore = clock_getlogicaltime(); - int res = send(sockfd, buf, length-sent, 0); - double timeafter = clock_getlogicaltime(); - int late = (timeafter - timebefore > 0.005); - if (late || pleasewarn) - { - if (timeafter > lastwarntime + 2) - { - post("netserver blocked %d msec", - (int)(1000 * ((timeafter - timebefore) + pleasewarn))); - pleasewarn = 0; - lastwarntime = timeafter; - } - else if (late) pleasewarn += timeafter - timebefore; - } - if (res <= 0) - { - sys_sockerror("netserver"); - post("netserver: could not send data to cient"); - break; - } - else - { - sent += res; - bp += res; - } - } - t_freebytes(buf, length); - binbuf_free(b); - } - else post("netserver: not a valid socket number (%d)", sockfd); + int sockfd, client; + if(x->x_nconnections < 0) + { + if (x->x_log_pri >= LOG_WARNING) + post("netserver: no clients connected"); + return; + } + if(argc < 2) + { + if (x->x_log_pri >= LOG_WARNING) + post("netserver: nothing to send"); + return; + } + /* get number of client (first element in list) */ + if(argv[0].a_type == A_FLOAT) + client = atom_getfloatarg(0, argc, argv); + else + { + if (x->x_log_pri >= LOG_WARNING) + post("netserver: no client specified"); + return; + } + sockfd = x->x_fd[client - 1]; /* get socket number for that client */ + + /* process & send data */ + if(sockfd > 0) + { + t_binbuf *b = binbuf_new(); + char *buf, *bp; + int length, sent; + t_atom at; + binbuf_add(b, argc - 1, argv + 1); /* skip first element */ + SETSEMI(&at); + binbuf_add(b, 1, &at); + binbuf_gettext(b, &buf, &length); + + if (x->x_log_pri >= LOG_DEBUG) + { + post("netserver: sending data to client %d on socket %d", client, sockfd); + post("netserver: >> sending \"%s\"", buf); + } + + for (bp = buf, sent = 0; sent < length;) + { + static double lastwarntime; + static double pleasewarn; + double timebefore = clock_getlogicaltime(); + int res = send(sockfd, buf, length-sent, 0); + double timeafter = clock_getlogicaltime(); + int late = (timeafter - timebefore > 0.005); + if (late || pleasewarn) + { + if (timeafter > lastwarntime + 2) + { + if (x->x_log_pri >= LOG_WARNING) + post("netserver blocked %d msec", + (int)(1000 * ((timeafter - timebefore) + pleasewarn))); + pleasewarn = 0; + lastwarntime = timeafter; + } + else if (late) pleasewarn += timeafter - timebefore; + } + if (res <= 0) + { + sys_sockerror("netserver"); + if (x->x_log_pri >= LOG_ERR) + post("netserver: could not send data to cient"); + break; + } + else + { + sent += res; + bp += res; + } + } + t_freebytes(buf, length); + binbuf_free(b); + } + else if (x->x_log_pri >= LOG_CRIT) + post("netserver: not a valid socket number (%d)", sockfd); } - /* broadcasts a message to all connected clients */ +/* broadcasts a message to all connected clients */ static void netserver_broadcast(t_netserver *x, t_symbol *s, int argc, t_atom *argv) { - int i, client = x->x_nconnections; /* number of clients to send to */ - t_atom at[256]; - for(i = 0; i < argc; i++) - { - at[i + 1] = argv[i]; - } - argc++; - /* enumerate through the clients and send each the message */ - while(client--) - { - SETFLOAT(at, client + 1); /* prepend number of client */ - netserver_client_send(x, s, argc, at); - } + int i, client = x->x_nconnections; /* number of clients to send to */ + t_atom at[256]; + for(i = 0; i < argc; i++) + { + at[i + 1] = argv[i]; + } + argc++; + /* enumerate through the clients and send each the message */ + while(client--) + { + SETFLOAT(at, client + 1); /* prepend number of client */ + netserver_client_send(x, s, argc, at); + } } @@ -375,211 +410,263 @@ static void netserver_broadcast(t_netserver *x, t_symbol *s, int argc, t_atom *a static void netserver_notify(t_netserver *x) { - int i, k; - /* remove connection from list */ - for(i = 0; i < x->x_nconnections; i++) - { - if(x->x_fd[i] == x->x_sock_fd) - { - x->x_nconnections--; - post("netserver: \"%s\" removed from list of clients", x->x_host[i]->s_name); - x->x_host[i] = NULL; /* delete entry */ - x->x_fd[i] = -1; - /* rearrange list now: move entries to close the gap */ - for(k = i; k < x->x_nconnections; k++) - { - x->x_host[k] = x->x_host[k + 1]; - x->x_fd[k] = x->x_fd[k + 1]; - } - } - } - outlet_float(x->x_connectout, x->x_nconnections); + int i, k; + /* remove connection from list */ + for(i = 0; i < x->x_nconnections; i++) + { + if(x->x_fd[i] == x->x_sock_fd) + { + x->x_nconnections--; + if (x->x_log_pri >= LOG_NOTICE) + post("netserver: \"%s\" removed from list of clients", x->x_host[i]->s_name); + x->x_host[i] = NULL; /* delete entry */ + x->x_fd[i] = -1; + /* rearrange list now: move entries to close the gap */ + for(k = i; k < x->x_nconnections; k++) + { + x->x_host[k] = x->x_host[k + 1]; + x->x_fd[k] = x->x_fd[k + 1]; + } + } + } + outlet_float(x->x_connectout, x->x_nconnections); } static void netserver_doit(void *z, t_binbuf *b) { - t_atom messbuf[1024]; - t_netserver *x = (t_netserver *)z; - int msg, natom = binbuf_getnatom(b); - t_atom *at = binbuf_getvec(b); - int i; - /* output clients IP and socket no. */ - for(i = 0; i < x->x_nconnections; i++) /* search for corresponding IP */ - { - if(x->x_fd[i] == x->x_sock_fd) - { - outlet_symbol(x->x_connectionip, x->x_host[i]); - break; - } - } - outlet_float(x->x_clientno, x->x_sock_fd); /* the socket number */ - /* process data */ - for (msg = 0; msg < natom;) - { - int emsg; - for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA - && at[emsg].a_type != A_SEMI; emsg++); - - if (emsg > msg) - { - int ii; - for (ii = msg; ii < emsg; ii++) - if (at[ii].a_type == A_DOLLAR || at[ii].a_type == A_DOLLSYM) - { - pd_error(x, "netserver: got dollar sign in message"); - goto nodice; - } - if (at[msg].a_type == A_FLOAT) + t_atom messbuf[1024]; + t_netserver *x = (t_netserver *)z; + int msg, natom = binbuf_getnatom(b); + t_atom *at = binbuf_getvec(b); + int i; + /* output clients IP and socket no. */ + for(i = 0; i < x->x_nconnections; i++) /* search for corresponding IP */ + { + if(x->x_fd[i] == x->x_sock_fd) + { + outlet_symbol(x->x_connectionip, x->x_host[i]); + break; + } + } + outlet_float(x->x_clientno, x->x_sock_fd); /* the socket number */ + /* process data */ + for (msg = 0; msg < natom;) + { + int emsg; + for (emsg = msg; emsg < natom && at[emsg].a_type != A_COMMA + && at[emsg].a_type != A_SEMI; emsg++); + + if (emsg > msg) + { + int ii; + for (ii = msg; ii < emsg; ii++) + if (at[ii].a_type == A_DOLLAR || at[ii].a_type == A_DOLLSYM) { - if (emsg > msg + 1) - outlet_list(x->x_msgout, 0, emsg-msg, at + msg); - else outlet_float(x->x_msgout, at[msg].a_w.w_float); + pd_error(x, "netserver: got dollar sign in message"); + goto nodice; } - else if (at[msg].a_type == A_SYMBOL) - outlet_anything(x->x_msgout, at[msg].a_w.w_symbol, - emsg-msg-1, at + msg + 1); - } - nodice: - msg = emsg + 1; - } + if (at[msg].a_type == A_FLOAT) + { + if (emsg > msg + 1) + outlet_list(x->x_msgout, 0, emsg-msg, at + msg); + else outlet_float(x->x_msgout, at[msg].a_w.w_float); + } + else if (at[msg].a_type == A_SYMBOL) + outlet_anything(x->x_msgout, at[msg].a_w.w_symbol, + emsg-msg-1, at + msg + 1); + } + nodice: + msg = emsg + 1; + } } static void netserver_connectpoll(t_netserver *x) { - struct sockaddr_in incomer_address; - int sockaddrl = (int) sizeof( struct sockaddr ); - int fd = accept(x->x_connectsocket, (struct sockaddr*)&incomer_address, &sockaddrl); - if (fd < 0) post("netserver: accept failed"); - else - { - t_netserver_socketreceiver *y = netserver_socketreceiver_new((void *)x, - (t_netserver_socketnotifier)netserver_notify, - (x->x_msgout ? netserver_doit : 0)); - sys_addpollfn(fd, (t_fdpollfn)netserver_socketreceiver_read, y); - x->x_nconnections++; - x->x_host[x->x_nconnections - 1] = gensym(inet_ntoa(incomer_address.sin_addr)); - x->x_fd[x->x_nconnections - 1] = fd; - - post("netserver: ** accepted connection from %s on socket %d", - x->x_host[x->x_nconnections - 1]->s_name, x->x_fd[x->x_nconnections - 1]); - outlet_float(x->x_connectout, x->x_nconnections); - } + struct sockaddr_in incomer_address; + int sockaddrl = (int) sizeof( struct sockaddr ); + int fd = accept(x->x_connectsocket, (struct sockaddr*)&incomer_address, &sockaddrl); + if (fd < 0) post("netserver: accept failed"); + else + { + t_netserver_socketreceiver *y = netserver_socketreceiver_new((void *)x, + (t_netserver_socketnotifier)netserver_notify, + (x->x_msgout ? netserver_doit : 0)); + sys_addpollfn(fd, (t_fdpollfn)netserver_socketreceiver_read, y); + x->x_nconnections++; + x->x_host[x->x_nconnections - 1] = gensym(inet_ntoa(incomer_address.sin_addr)); + x->x_fd[x->x_nconnections - 1] = fd; + + if (x->x_log_pri >= LOG_NOTICE) + post("netserver: ** accepted connection from %s on socket %d", + x->x_host[x->x_nconnections - 1]->s_name, x->x_fd[x->x_nconnections - 1]); + outlet_float(x->x_connectout, x->x_nconnections); + } } static void netserver_print(t_netserver *x) { - int i; - if(x->x_nconnections > 0) - { - post("netserver: %d open connections:", x->x_nconnections); - - for(i = 0; i < x->x_nconnections; i++) - { - post(" \"%s\" on socket %d", - x->x_host[i]->s_name, x->x_fd[i]); - } - } else post("netserver: no open connections"); + int i; + if(x->x_nconnections > 0) + { + post("netserver: %d open connections:", x->x_nconnections); + + for(i = 0; i < x->x_nconnections; i++) + { + post(" \"%s\" on socket %d", + x->x_host[i]->s_name, x->x_fd[i]); + } + } else post("netserver: no open connections"); +} + +static void netserver_emerg(t_netserver *x) +{ + x->x_log_pri = LOG_EMERG; +} +static void netserver_alert(t_netserver *x) +{ + x->x_log_pri = LOG_ALERT; +} +static void netserver_crit(t_netserver *x) +{ + x->x_log_pri = LOG_CRIT; +} +static void netserver_err(t_netserver *x) +{ + x->x_log_pri = LOG_ERR; +} +static void netserver_warning(t_netserver *x) +{ + x->x_log_pri = LOG_WARNING; +} +static void netserver_notice(t_netserver *x) +{ + x->x_log_pri = LOG_NOTICE; +} +static void netserver_info(t_netserver *x) +{ + x->x_log_pri = LOG_INFO; +} +static void netserver_debug(t_netserver *x) +{ + x->x_log_pri = LOG_DEBUG; } static void *netserver_new(t_floatarg fportno) { - t_netserver *x; - int i; - struct sockaddr_in server; - int sockfd, portno = fportno; - /* create a socket */ - sockfd = socket(AF_INET, SOCK_STREAM, 0); -#if 0 - post("netserver: receive socket %d", sockfd); -#endif - if (sockfd < 0) - { - sys_sockerror("socket"); - return (0); - } - server.sin_family = AF_INET; - server.sin_addr.s_addr = INADDR_ANY; + t_netserver *x; + int i; + struct sockaddr_in server; + int sockfd, portno = fportno; + + x = (t_netserver *)pd_new(netserver_class); +/* set default debug message level */ + x->x_log_pri = LOG_ERR; +/* create a socket */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (x->x_log_pri >= LOG_NOTICE) + post("netserver: receive socket %d", sockfd); + if (sockfd < 0) + { + sys_sockerror("socket"); + return (0); + } + server.sin_family = AF_INET; + server.sin_addr.s_addr = INADDR_ANY; #ifdef IRIX - /* this seems to work only in IRIX but is unnecessary in - Linux. Not sure what NT needs in place of this. */ - if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0) - post("setsockopt failed\n"); + /* this seems to work only in IRIX but is unnecessary in + Linux. Not sure what NT needs in place of this. */ + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 0, 0) < 0) + post("setsockopt failed\n"); #endif - /* assign server port number */ - server.sin_port = htons((u_short)portno); - - /* name the socket */ - if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) - { - sys_sockerror("bind"); - sys_closesocket(sockfd); - return (0); - } - x = (t_netserver *)pd_new(netserver_class); - x->x_msgout = outlet_new(&x->x_obj, &s_anything); - - /* streaming protocol */ - if (listen(sockfd, 5) < 0) - { - sys_sockerror("listen"); - sys_closesocket(sockfd); - sockfd = -1; - } - else - { - sys_addpollfn(sockfd, (t_fdpollfn)netserver_connectpoll, x); - x->x_connectout = outlet_new(&x->x_obj, &s_float); - x->x_clientno = outlet_new(&x->x_obj, &s_float); - x->x_connectionip = outlet_new(&x->x_obj, &s_symbol); - inbinbuf = binbuf_new(); - } - x->x_connectsocket = sockfd; - x->x_nconnections = 0; - for(i = 0; i < MAX_CONNECT; i++)x->x_fd[i] = -1; - - return (x); + /* assign server port number */ + server.sin_port = htons((u_short)portno); + + /* name the socket */ + if (bind(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0) + { + sys_sockerror("bind"); + sys_closesocket(sockfd); + return (0); + } + x->x_msgout = outlet_new(&x->x_obj, &s_anything); + + /* streaming protocol */ + if (listen(sockfd, 5) < 0) + { + sys_sockerror("listen"); + sys_closesocket(sockfd); + sockfd = -1; + } + else + { + sys_addpollfn(sockfd, (t_fdpollfn)netserver_connectpoll, x); + x->x_connectout = outlet_new(&x->x_obj, &s_float); + x->x_clientno = outlet_new(&x->x_obj, &s_float); + x->x_connectionip = outlet_new(&x->x_obj, &s_symbol); + inbinbuf = binbuf_new(); + } + x->x_connectsocket = sockfd; + x->x_nconnections = 0; + for(i = 0; i < MAX_CONNECT; i++)x->x_fd[i] = -1; + + return (x); } static void netserver_free(t_netserver *x) { - int i; - for(i = 0; i < x->x_nconnections; i++) - { - sys_rmpollfn(x->x_fd[i]); - sys_closesocket(x->x_fd[i]); - } - if (x->x_connectsocket >= 0) - { - sys_rmpollfn(x->x_connectsocket); - sys_closesocket(x->x_connectsocket); - } - binbuf_free(inbinbuf); + int i; + for(i = 0; i < x->x_nconnections; i++) + { + sys_rmpollfn(x->x_fd[i]); + sys_closesocket(x->x_fd[i]); + } + if (x->x_connectsocket >= 0) + { + sys_rmpollfn(x->x_connectsocket); + sys_closesocket(x->x_connectsocket); + } + binbuf_free(inbinbuf); } #ifndef MAXLIB void netserver_setup(void) { - netserver_class = class_new(gensym("netserver"),(t_newmethod)netserver_new, (t_method)netserver_free, - sizeof(t_netserver), 0, A_DEFFLOAT, 0); - class_addmethod(netserver_class, (t_method)netserver_print, gensym("print"), 0); - class_addmethod(netserver_class, (t_method)netserver_send, gensym("send"), A_GIMME, 0); - class_addmethod(netserver_class, (t_method)netserver_client_send, gensym("client"), A_GIMME, 0); - class_addmethod(netserver_class, (t_method)netserver_broadcast, gensym("broadcast"), A_GIMME, 0); - class_sethelpsymbol(netserver_class, gensym("help-netserver.pd")); - post(version); + netserver_class = class_new(gensym("netserver"),(t_newmethod)netserver_new, (t_method)netserver_free, + sizeof(t_netserver), 0, A_DEFFLOAT, 0); + class_addmethod(netserver_class, (t_method)netserver_print, gensym("print"), 0); + class_addmethod(netserver_class, (t_method)netserver_send, gensym("send"), A_GIMME, 0); + class_addmethod(netserver_class, (t_method)netserver_client_send, gensym("client"), A_GIMME, 0); + class_addmethod(netserver_class, (t_method)netserver_broadcast, gensym("broadcast"), A_GIMME, 0); +/* syslog log level messages */ + class_addmethod(netserver_class, (t_method)netserver_emerg, gensym("emerg"), 0); + class_addmethod(netserver_class, (t_method)netserver_emerg, gensym("emergency"), 0); + class_addmethod(netserver_class, (t_method)netserver_alert, gensym("alert"), 0); + class_addmethod(netserver_class, (t_method)netserver_crit, gensym("crit"), 0); + class_addmethod(netserver_class, (t_method)netserver_crit, gensym("critical"), 0); + class_addmethod(netserver_class, (t_method)netserver_err, gensym("err"), 0); + class_addmethod(netserver_class, (t_method)netserver_err, gensym("error"), 0); + class_addmethod(netserver_class, (t_method)netserver_err, gensym("quiet"), 0); + class_addmethod(netserver_class, (t_method)netserver_warning, gensym("warning"), 0); + class_addmethod(netserver_class, (t_method)netserver_notice, gensym("notice"), 0); + class_addmethod(netserver_class, (t_method)netserver_info, gensym("info"), 0); + class_addmethod(netserver_class, (t_method)netserver_info, gensym("verbose"), 0); + class_addmethod(netserver_class, (t_method)netserver_debug, gensym("debug"), 0); + + class_sethelpsymbol(netserver_class, gensym("help-netserver.pd")); + post(version); } #else void maxlib_netserver_setup(void) { - netserver_class = class_new(gensym("maxlib_netserver"),(t_newmethod)netserver_new, (t_method)netserver_free, - sizeof(t_netserver), 0, A_DEFFLOAT, 0); - class_addcreator((t_newmethod)netserver_new, gensym("netserver"), A_DEFFLOAT, 0); - class_addmethod(netserver_class, (t_method)netserver_print, gensym("print"), 0); - class_addmethod(netserver_class, (t_method)netserver_send, gensym("send"), A_GIMME, 0); - class_addmethod(netserver_class, (t_method)netserver_client_send, gensym("client"), A_GIMME, 0); - class_addmethod(netserver_class, (t_method)netserver_broadcast, gensym("broadcast"), A_GIMME, 0); - class_sethelpsymbol(netserver_class, gensym("maxlib/help-netserver.pd")); + netserver_class = class_new(gensym("maxlib_netserver"),(t_newmethod)netserver_new, (t_method)netserver_free, + sizeof(t_netserver), 0, A_DEFFLOAT, 0); + class_addcreator((t_newmethod)netserver_new, gensym("netserver"), A_DEFFLOAT, 0); + class_addmethod(netserver_class, (t_method)netserver_print, gensym("print"), 0); + class_addmethod(netserver_class, (t_method)netserver_send, gensym("send"), A_GIMME, 0); + class_addmethod(netserver_class, (t_method)netserver_client_send, gensym("client"), A_GIMME, 0); + class_addmethod(netserver_class, (t_method)netserver_broadcast, gensym("broadcast"), A_GIMME, 0); + class_sethelpsymbol(netserver_class, gensym("maxlib/help-netserver.pd")); } #endif -- cgit v1.2.1