home *** CD-ROM | disk | FTP | other *** search
- /* sock_xex . c
- #
- % Copyright (c) Jin Guojun
- %
- % Socket X-extended Server
- % If RTP is initialized, and it is not impelmented in kernel method;
- % then, we need a special rtp_read routine to read incoming data.
- %
- % AUTHOR: Jin Guojun - LBL 01/01/93
- */
-
- #include <fcntl.h>
- #include "net_need.h"
-
- #ifndef SERVER
- #define SERVER "s_master"
- #endif
-
-
- static rtpmsg_hd msg_hdr;
- static char buf[1024], **plist;
- static int pnum, as, so;
- static magic_server ss[2]; /* 0 for TCP, and 1 for RTP or others */
- static struct sockaddr_in sain;
-
- build_arg_list(char *buf, char **tpp[])
- {
- register int i, n, p = n = 0;
- char* *lp;
- Loop {
- n++;
- if (!(i = strchr(buf+p, Space))) break;
- i -= (int)buf;
- buf[i++] = 0; /* add terminator */
- p = i;
- } n++;
- verify_buffer_size(tpp, n--, sizeof(tpp), "tpp");
- lp = *tpp;
- lp[p=0] = "socket";
- for (i=p; i++ < n;) { /* start from second ap */
- lp[i] = buf + p;
- while (buf[p++]);
- }
- return n;
- }
-
- get_arg_list(int *rpp)
- {
- if (rpp)
- *rpp = (int)plist;
- return pnum;
- }
-
- x_extender_init(char *server_name, bool udp, int buf_size)
- {
- if (!server_name)
- sprintf(server_name=buf, "%s", SERVER);
- sain.sin_addr.s_addr = INADDR_ANY;
- retryexi:
- if (buf_size < 4096 || buf_size > Max_WINDOW_SIZE)
- buf_size=Max_WINDOW_SIZE;
- if ((so=build_socket(NULL, server_name,
- udp ? udp==1 ? SOCK_DGRAM : SOCK_RAW : SOCK_STREAM,
- False, &buf_size, &sain, ss+(udp!=0))) < 0 &&
- errno == EADDRINUSE) {
- if (sain.sin_port == SV_PORT)
- return prgmerr(0, "%d:bind[%d] -> port = %d",
- udp, so, sain.sin_port);
- sprintf(server_name=buf, "%d", SV_PORT);
- goto retryexi;
- }
- if (!udp) listen(so, 4);
- return sain.sin_port;
- }
-
- FILE*
- x_extender(bool udp)
- {
- fd_set ready;
- int l;
- short psize;
- register int i;
-
- struct timeval to;
- FD_ZERO(&ready);
- FD_SET(so = ss[udp].so, &ready);
- to.tv_sec = 0; to.tv_usec = 100000;
- if ((i=select(so+1, &ready, 0, 0, &to)) < 0 && DEBUGANY)
- msg(" select %d(%d) ", i, so);
- if (FD_ISSET(so, &ready)) {
- if (!ss[udp].connected) {
- l = sizeof(sain);
- ss[udp].as = as = udp ? so : accept(so, &sain, &l);
- #ifdef _DEBUG_
- msg("select returns %d[%d]{%X}\t", so, as, i);
- #endif
- if (as > 0) {
- if (fcntl(as, F_SETOWN, getpid())<0)
- syserr("F_SETOWN %d", getpid());
- if (fcntl(as, F_SETFL, FASYNC)<0)
- syserr("F_SETEL FASYNC");
- ss[udp].connected++;
- ss[udp].stat = ss[udp].dp = pnum = 0;
- if ((ss[udp].fp=fdopen(as, "rb"))) {
- if ((i=fgetc(ss[udp].fp)) == '#')
- if (!(l=fgetc(ss[udp].fp))) {
- fread(&psize, 1, sizeof(short), ss[udp].fp);
- i = htons(psize) + 1; /* NULL terminator */
- fread(&msg_hdr, 1, sizeof(msg_hdr), ss[udp].fp);
- fread(buf, 1, i, ss[udp].fp);
- gettimeofday(&ss[udp].ts, 0);
- msg_hdr.tsr_s = ss[udp].ts.tv_sec;
- msg_hdr.tsr_us = ss[udp].ts.tv_usec;
- pnum = build_arg_list(buf, &plist);
- #ifdef _DEBUG_
- msg("params size %d {# %d}\n", i, pnum);
- #endif
- } else ungetc(l, ss[udp].fp),
- ungetc('#', ss[udp].fp);
- else ungetc(i, ss[udp].fp);
- #ifdef _DEBUG_
- msg("#1 = %c [%d], #2 = %d\n", i, i, l);
- #endif /* params start with "#" ('#'\0) */
- return i<0 ? (FILE*)EOF : ss[udp].fp;
- } else return (FILE*)prgmerr(0, "fdopen");
- }
- } if (udp) goto disc;
- message("%d: something happened %d\n", ss[udp].connected, as);
- } else if (ss[udp].connected) {
- FD_ZERO(&ready);
- FD_SET(as, &ready);
- i = select(as+1, &ready, 0, 0, &to);
- #ifdef _DEBUG_
- msg("%d {%X} %d\n", i, FD_ISSET(as, &ready), to.tv_usec);
- #endif
- if (i && FD_ISSET(as, &ready)) {
- /* close(as); /* prepare to reconnect */
- disc: fclose(ss[udp].fp);
- ss[udp].connected = 0;
- if (udp) x_extender_init(0, udp, 0);
- #ifdef _DEBUG_
- fprintf(stderr, "\t%d(%d): disconnect at {%X}\n",
- i, as, FD_ISSET(as, &ready));
- #endif
- }
- }
- fflush(stderr);
- return NULL;
- }
-