home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d145 / dnet.lha / Dnet / unix / dnet / subs.c < prev    next >
C/C++ Source or Header  |  1988-05-26  |  7KB  |  334 lines

  1.  
  2. /*
  3.  *  SUBS.C
  4.  *
  5.  *    DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  6.  *
  7.  *    Support subroutines
  8.  *
  9.  */
  10.  
  11. #include "dnet.h"
  12.  
  13. /*
  14.  *   WRITESTREAM()
  15.  *
  16.  *    Queues new SCMD_?? level commands to be sent
  17.  */
  18.  
  19. WriteStream(sdcmd, buf, len, chan)
  20. ubyte *buf;
  21. uword chan;
  22. {
  23.     register XIOR *ior = (XIOR *)malloc(sizeof(XIOR));
  24.  
  25.     if (DDebug)
  26.     fprintf(stderr, "**SEND MPX CMD %ld (%ld bytes on channel %ld)\n", 
  27.         sdcmd, len, chan
  28.     );
  29.  
  30.     ior->io_Data = (ubyte *)malloc(len);
  31.     ior->io_Length = len;
  32.     ior->io_Actual = 0;
  33.     ior->io_Command = sdcmd;
  34.     ior->io_Error = 0;
  35.     ior->io_Channel = chan;
  36.     ior->io_Pri = (chan > MAXCHAN) ? 126 : Chan[chan].pri;
  37.     bcopy(buf, ior->io_Data, len);
  38.     Enqueue(&TxList, ior);
  39.     do_wupdate();
  40. }
  41.  
  42. /*
  43.  *  ALLOC_CHANNEL()
  44.  *
  45.  *    Allocate a free channel.  Used in SCMD_OPEN and SCMD_ACKCMD
  46.  */
  47.  
  48. alloc_channel()
  49. {
  50.     static ulong ran = 13;
  51.     register uword i;
  52.  
  53.     ran = ((ran * 13) + 1) ^ (ran >> 9) + time(0);
  54.     for (i = ran % MAXCHAN; i < MAXCHAN; ++i) {
  55.     if (Chan[i].state == 0)
  56.         return(i);
  57.     }
  58.     for (i = ran % MAXCHAN; i < MAXCHAN; --i) {
  59.     if (Chan[i].state == 0)
  60.         return(i);
  61.     }
  62.     return(-1);
  63. }
  64.  
  65. /*
  66.  *    Remove all nodes with the given channel ID.
  67.  */
  68.  
  69. ClearChan(list, chan, all)
  70. LIST *list;
  71. uword chan;
  72. {
  73.     register XIOR *io, *in;
  74.  
  75.     for (io = (XIOR *)list->lh_Head; io != (XIOR *)&list->lh_Tail; io = in) {
  76.     in = (XIOR *)io->io_Node.ln_Succ;
  77.     if (io->io_Channel == chan) {
  78.         if (all || io->io_Command == SCMD_DATA) {
  79.             io->io_Node.ln_Succ->ln_Pred = io->io_Node.ln_Pred;
  80.             io->io_Node.ln_Pred->ln_Succ = io->io_Node.ln_Succ;
  81.             free(io->io_Data);
  82.             free(io);
  83.         }
  84.     }
  85.     }
  86. }
  87.  
  88. /*
  89.  *  Queue a packet into a prioritized list.  FIFO is retained for packets
  90.  *  of the same priority.  This implements one level of channel priorities,
  91.  *  before the packets actually get queued to the network.  Since up to
  92.  *  4 packets might be queued (200 * 4 = 800 bytes of data or 4 seconds @ 
  93.  *  2400 baud), a second level of prioritization will also reduce the
  94.  *  physical packet size when two channels at relatively large differing
  95.  *  priorities are in use.
  96.  *
  97.  *    These and other list routines compatible with Amiga list routines.
  98.  */
  99.  
  100. Enqueue(list, ior)
  101. LIST *list;
  102. XIOR *ior;
  103. {
  104.     register XIOR *io;
  105.     char pri = ior->io_Pri;
  106.  
  107.     io = (XIOR *)list->lh_Head;
  108.     while (io != (XIOR *)&list->lh_Tail) {
  109.     if (pri > io->io_Pri)
  110.         break;
  111.     io = (XIOR *)io->io_Node.ln_Succ;
  112.     }
  113.     ior->io_Node.ln_Succ = (NODE *)io;
  114.     ior->io_Node.ln_Pred = io->io_Node.ln_Pred;
  115.     ior->io_Node.ln_Succ->ln_Pred = (NODE *)ior;
  116.     ior->io_Node.ln_Pred->ln_Succ = (NODE *)ior;
  117. }
  118.  
  119. AddTail(list, node)
  120. LIST *list;
  121. NODE *node;
  122. {
  123.     node->ln_Succ = (NODE *)&list->lh_Tail;
  124.     node->ln_Pred = list->lh_TailPred;
  125.     node->ln_Succ->ln_Pred = node;
  126.     node->ln_Pred->ln_Succ = node;
  127. }
  128.  
  129. AddHead(list, node)
  130. LIST *list;
  131. NODE *node;
  132. {
  133.     node->ln_Succ = list->lh_Head;
  134.     node->ln_Pred = (NODE *)list;
  135.     node->ln_Succ->ln_Pred = node;
  136.     node->ln_Pred->ln_Succ = node;
  137. }
  138.  
  139. ubyte *
  140. RemHead(list)
  141. LIST *list;
  142. {
  143.     NODE *node;
  144.  
  145.     node = list->lh_Head;
  146.     if (node->ln_Succ == NULL)
  147.     return(NULL);
  148.     node->ln_Succ->ln_Pred = node->ln_Pred;
  149.     node->ln_Pred->ln_Succ = node->ln_Succ;
  150.     return((ubyte *)node);
  151. }
  152.  
  153. NewList(list)
  154. LIST *list;
  155. {
  156.     list->lh_Head = (NODE *)&list->lh_Tail;
  157.     list->lh_Tail = NULL;
  158.     list->lh_TailPred = (NODE *)&list->lh_Head;
  159. }
  160.  
  161. GetNext(node)
  162. NODE *node;
  163. {
  164.     register NODE *next = node->ln_Succ;
  165.     if (*(long *)next)
  166.     return((long)next);
  167.     return(NULL);
  168. }
  169.  
  170. /*
  171.  *  CHKBUF
  172.  *
  173.  *    Checksum a buffer.  Uses a simple, but supposedly very good 
  174.  *    scheme.
  175.  */
  176.  
  177. chkbuf(buf, bytes)
  178. register ubyte *buf;
  179. register uword bytes;
  180. {
  181.     register uword i;
  182.     register ubyte c1,c2;
  183.  
  184.     for (i = c1 = c2 = 0; i < bytes; ++i) {
  185.     c1 += buf[i];
  186.     c2 += c1;
  187.     }
  188.     c1 = -(c1 + c2);
  189.     return((c1<<8)|c2);
  190. }
  191.  
  192. /*
  193.  *   Write timeout signal handler.
  194.  */
  195.  
  196. sigwto()
  197. {
  198.     WTimedout = 1;
  199.     Wto_act = 0;
  200. }
  201.  
  202. TimerOpen()
  203. {
  204.     static struct sigvec SA = { sigwto, 0, 0 };
  205.     sigvec(SIGALRM, &SA, NULL);
  206. }
  207.  
  208. TimerClose()
  209. {
  210.     signal(SIGALRM, SIG_IGN);
  211. }
  212.  
  213. WTimeout(us)
  214. {
  215.     static struct itimerval itv;
  216.     struct itimerval ov;
  217.     long mask;
  218.  
  219.     itv.it_value.tv_sec = us / 1000000;
  220.     itv.it_value.tv_usec= (us % 1000000);
  221.  
  222.     mask = sigblock(sigmask(SIGALRM));
  223.     setitimer(ITIMER_REAL, &itv, &ov);
  224.     Wto_act = 1;
  225.     WTimedout = 0;
  226.     sigsetmask(mask);
  227.     if (DDebug)
  228.     fprintf(stderr, "WTimeout set\n");
  229. }
  230.  
  231. dneterror(str)
  232. char *str;
  233. {
  234.     register short i;
  235.  
  236.     NetClose();
  237.     TimerClose();
  238.     exit(1);
  239. }
  240.  
  241. /*
  242.  *    setenv(name, str).  name must be of the form "NAME="
  243.  */
  244.  
  245. setenv(name, str)
  246. char *name;
  247. char *str;
  248. {
  249.     extern char **environ;
  250.     static char **elist;
  251.     static int elen;
  252.     char *ptr;
  253.     int i, len;
  254.  
  255.     len = strlen(name);
  256.     if (elist == NULL) {
  257.     for (i = 0; environ[i]; ++i);
  258.     elist = (char **)malloc((i+3)*sizeof(char *));
  259.     elen = i + 3;
  260.     bcopy(environ, elist, i*sizeof(char *));
  261.     environ = elist;
  262.     }
  263.     for (i = 0; elist[i]; ++i) {
  264.     if (strncmp(elist[i], name, len) == 0)
  265.         break;
  266.     }
  267.     if (i == elen) {
  268.     elen += 4;
  269.     elist = environ = (char **)realloc(elist, elen*sizeof(char *));
  270.     }
  271.     ptr = (char *)malloc(len + strlen(str) + 1);
  272.     sprintf(ptr, "%s%s", name, str);
  273.     if (elist[i]) {
  274.     elist[i] = ptr;
  275.     } else {
  276.     elist[i] = ptr;
  277.     elist[i+1] = NULL;
  278.     elen = i + 1;
  279.     }
  280. }
  281.  
  282. void
  283. startserver(port)
  284. uword port;
  285. {
  286.     char *dir = (getenv("DNETDIR"))?getenv("DNETDIR"):"./";
  287.     char buf[256];
  288.     char path[128];
  289.     char cdir[128];
  290.     long portno;
  291.     FILE *fi;
  292.  
  293.     sprintf(buf, "%sdnet.servers", dir);
  294.     if (!port || (fi = fopen(buf, "r")) == NULL)
  295.     return;
  296.     while (fgets(buf, 256, fi)) {
  297.     if (sscanf(buf, "%ld %s %s", &portno, path, cdir) == 3) {
  298.         if (portno == port) {
  299.         if (!fork()) {
  300.                 int i;
  301.             fclose(fi);
  302.             /*
  303.             if (chdir(cdir) < 0) {
  304.             fprintf(stderr, "Unable to set server dir %s\n", cdir);
  305.             _exit(1);
  306.             }
  307.             */
  308.                 setuid(getuid());
  309.                 signal(SIGHUP, SIG_DFL);
  310.                 signal(SIGINT, SIG_DFL);
  311.                 signal(SIGQUIT, SIG_DFL);
  312.                 signal(SIGTERM, SIG_DFL);
  313.                 signal(SIGCHLD, SIG_DFL);
  314.                 signal(SIGTSTP, SIG_IGN);
  315.                 ioctl(open("/dev/tty", 2), TIOCNOTTY, NULL);
  316.             i = open("/dev/null", O_RDWR, 0);
  317.             dup2(i, 0);
  318.             dup2(i, 1);
  319.                 for (i = 3; i < 256; ++i)
  320.                 close(i);
  321.             sprintf(buf, "server.%ld.%ld", port, getuid());
  322.             execl(path, buf, cdir, NULL);
  323.             fprintf(stderr, "Unable to exec server: %s\n", path);
  324.             _exit(1);
  325.         }
  326.         sleep(4);    /* is a hack */
  327.         break;
  328.         }
  329.     }
  330.     }
  331.     fclose(fi);
  332. }
  333.  
  334.