home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / procssng / ccs / ccs-11tl.lha / lbl / x11 / lib2 / sock_xex.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-10  |  3.7 KB  |  150 lines

  1. /*    sock_xex . c
  2. #
  3. %    Copyright (c)    Jin Guojun
  4. %
  5. %    Socket X-extended Server
  6. %    If RTP is initialized, and it is not impelmented in kernel method;
  7. %    then, we need a special rtp_read routine to read incoming data.
  8. %
  9. % AUTHOR:    Jin Guojun - LBL    01/01/93
  10. */
  11.  
  12. #include <fcntl.h>
  13. #include "net_need.h"
  14.  
  15. #ifndef    SERVER
  16. #define    SERVER    "s_master"
  17. #endif
  18.  
  19.  
  20. static    rtpmsg_hd    msg_hdr;
  21. static    char    buf[1024], **plist;
  22. static    int    pnum, as, so;
  23. static    magic_server    ss[2];    /* 0 for TCP, and 1 for RTP or others    */
  24. static    struct sockaddr_in    sain;
  25.  
  26. build_arg_list(char *buf, char **tpp[])
  27. {
  28. register int    i, n, p = n = 0;
  29. char*    *lp;
  30.     Loop    {
  31.         n++;
  32.         if (!(i = strchr(buf+p, Space)))    break;
  33.         i -= (int)buf;
  34.         buf[i++] = 0;    /* add terminator    */
  35.         p = i;
  36.     }    n++;
  37.     verify_buffer_size(tpp, n--, sizeof(tpp), "tpp");
  38.     lp = *tpp;
  39.     lp[p=0] = "socket";
  40.     for (i=p; i++ < n;)    {    /* start from second ap    */
  41.         lp[i] = buf + p;
  42.         while (buf[p++]);
  43.     }
  44. return    n;
  45. }
  46.  
  47. get_arg_list(int *rpp)
  48. {
  49. if (rpp)
  50.     *rpp = (int)plist;
  51. return    pnum;
  52. }
  53.  
  54. x_extender_init(char *server_name, bool udp, int buf_size)
  55. {
  56.     if (!server_name)
  57.         sprintf(server_name=buf, "%s", SERVER);
  58.     sain.sin_addr.s_addr = INADDR_ANY;
  59. retryexi:
  60.     if (buf_size < 4096 || buf_size > Max_WINDOW_SIZE)
  61.         buf_size=Max_WINDOW_SIZE;
  62.     if ((so=build_socket(NULL, server_name,
  63.         udp ? udp==1 ? SOCK_DGRAM : SOCK_RAW : SOCK_STREAM,
  64.         False, &buf_size, &sain, ss+(udp!=0))) < 0 &&
  65.     errno == EADDRINUSE)    {
  66.         if (sain.sin_port == SV_PORT)
  67.             return    prgmerr(0, "%d:bind[%d] -> port = %d",
  68.                 udp, so, sain.sin_port);
  69.         sprintf(server_name=buf, "%d", SV_PORT);
  70.         goto    retryexi;
  71.     }
  72.     if (!udp)    listen(so, 4);
  73. return    sain.sin_port;
  74. }
  75.  
  76. FILE*
  77. x_extender(bool udp)
  78. {
  79. fd_set    ready;
  80. int    l;
  81. short    psize;
  82. register int    i;
  83.  
  84. struct timeval    to;
  85.     FD_ZERO(&ready);
  86.     FD_SET(so = ss[udp].so, &ready);
  87.     to.tv_sec = 0;    to.tv_usec = 100000;
  88.     if ((i=select(so+1, &ready, 0, 0, &to)) < 0 && DEBUGANY)
  89.         msg("    select %d(%d)    ", i, so);
  90.     if (FD_ISSET(so, &ready))    {
  91.         if (!ss[udp].connected)    {
  92.         l = sizeof(sain);
  93.         ss[udp].as = as = udp ? so : accept(so, &sain, &l);
  94. #ifdef    _DEBUG_
  95.         msg("select returns %d[%d]{%X}\t", so, as, i);
  96. #endif
  97.         if (as > 0)    {
  98.             if (fcntl(as, F_SETOWN,  getpid())<0)
  99.             syserr("F_SETOWN %d", getpid());
  100.             if (fcntl(as, F_SETFL, FASYNC)<0)
  101.             syserr("F_SETEL FASYNC");
  102.             ss[udp].connected++;
  103.             ss[udp].stat = ss[udp].dp = pnum = 0;
  104.             if ((ss[udp].fp=fdopen(as, "rb")))    {
  105.             if ((i=fgetc(ss[udp].fp)) == '#')
  106.                 if (!(l=fgetc(ss[udp].fp)))    {
  107.                 fread(&psize, 1, sizeof(short), ss[udp].fp);
  108.                 i = htons(psize) + 1;    /* NULL terminator */
  109.                 fread(&msg_hdr, 1, sizeof(msg_hdr), ss[udp].fp);
  110.                 fread(buf, 1, i, ss[udp].fp);
  111.                 gettimeofday(&ss[udp].ts, 0);
  112.                 msg_hdr.tsr_s = ss[udp].ts.tv_sec;
  113.                 msg_hdr.tsr_us = ss[udp].ts.tv_usec;
  114.                 pnum = build_arg_list(buf, &plist);
  115. #ifdef    _DEBUG_
  116.                 msg("params size %d {# %d}\n", i, pnum);
  117. #endif
  118.                 }    else    ungetc(l, ss[udp].fp),
  119.                     ungetc('#', ss[udp].fp);
  120.             else    ungetc(i, ss[udp].fp);
  121. #ifdef    _DEBUG_
  122.             msg("#1 = %c [%d], #2 = %d\n", i, i, l);
  123. #endif    /* params start with "#" ('#'\0)    */
  124.             return    i<0 ? (FILE*)EOF : ss[udp].fp;
  125.             } else    return    (FILE*)prgmerr(0, "fdopen");
  126.         }
  127.         }    if (udp)    goto    disc;
  128.         message("%d: something happened %d\n", ss[udp].connected, as);
  129.     } else if (ss[udp].connected)    {
  130.         FD_ZERO(&ready);
  131.         FD_SET(as, &ready);
  132.         i = select(as+1, &ready, 0, 0, &to);
  133. #ifdef    _DEBUG_
  134.         msg("%d {%X} %d\n", i, FD_ISSET(as, &ready), to.tv_usec);
  135. #endif
  136.         if (i && FD_ISSET(as, &ready))    {
  137.             /* close(as);    /* prepare to reconnect */
  138. disc:            fclose(ss[udp].fp);
  139.             ss[udp].connected = 0;
  140.             if (udp)    x_extender_init(0, udp, 0);
  141. #ifdef    _DEBUG_
  142.             fprintf(stderr, "\t%d(%d): disconnect at {%X}\n",
  143.                 i, as, FD_ISSET(as, &ready));
  144. #endif
  145.         }
  146.     }
  147.     fflush(stderr);
  148. return    NULL;
  149. }
  150.