home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 200-299 / ff294.lzh / DNet / unix / lib / dnetlib.c next >
C/C++ Source or Header  |  1989-12-11  |  6KB  |  361 lines

  1.  
  2. /*
  3.  *  DNETLIB.C
  4.  *
  5.  *    DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved
  6.  *
  7.  *  Library Interface for DNET.
  8.  */
  9.  
  10. #include <sys/types.h>
  11. #include <sys/socket.h>
  12. #include <fcntl.h>
  13. #include <signal.h>
  14. #include <stdio.h>
  15. #include <errno.h>
  16. #ifdef O_CREAT
  17. #include <sys/file.h>
  18. #endif
  19. #include "../lib/dnetlib.h"
  20.  
  21. extern char *getenv();
  22.  
  23. typedef unsigned short uword;
  24. typedef unsigned long ulong;
  25. typedef unsigned char ubyte;
  26. typedef struct sockaddr SOCKADDR;
  27.  
  28. typedef struct {
  29.     int s;
  30.     uword port;
  31. } CHANN;
  32.  
  33. #define NAMELEN sizeof(".PORT.XXXXX")
  34. #define NAMEPAT "%s.PORT.%ld"
  35.  
  36. char *getdirpart();
  37.  
  38. CHANN *
  39. DListen(port)
  40. uword port;
  41. {
  42.     CHANN *chan;
  43.     int s;
  44.     SOCKADDR *sa = (SOCKADDR *)malloc(sizeof(SOCKADDR)+256);
  45.     char *dirstr = getenv("DNETDIR") ? getenv("DNETDIR") : "";
  46.  
  47.     sprintf(sa->sa_data, NAMEPAT, dirstr, port);
  48.     sa->sa_family = AF_UNIX;
  49.     unlink(sa->sa_data);
  50.  
  51.     s = socket(PF_UNIX, SOCK_STREAM, 0);
  52.     fcntl(s, F_SETOWN, getpid());
  53.     if (bind(s, sa, sizeof(*sa)-sizeof(sa->sa_data)+strlen(sa->sa_data)) < 0) {
  54.     close(s);
  55.     free(sa);
  56.     return(NULL);
  57.     }
  58.     if (listen(s, 5) < 0) {
  59.     close(s);
  60.     unlink(sa->sa_data);
  61.     free(sa);
  62.     return(NULL);
  63.     }
  64.     chan = (CHANN *)malloc(sizeof(CHANN));
  65.     chan->s = s;
  66.     chan->port = port;
  67.     free(sa);
  68.     return(chan);
  69. }
  70.  
  71.  
  72. DUnListen(chan)
  73. CHANN *chan;
  74. {
  75.     char *dirstr = getenv("DNETDIR") ? getenv("DNETDIR") : "";
  76.     char buf[32];
  77.  
  78.     close(chan->s);
  79.     sprintf(buf, NAMEPAT, dirstr, chan->port);
  80.     unlink(buf);
  81.     free(chan);
  82. }
  83.  
  84. DAccept(chan)
  85. CHANN *chan;
  86. {
  87.     SOCKADDR sa;
  88.     int addrlen = sizeof(sa);
  89.     int fd;
  90.  
  91.     fd = accept(chan->s, &sa, &addrlen);
  92.     return(fd);
  93. }
  94.  
  95. DOpen(host, port, txpri, rxpri)
  96. char *host;
  97. uword port;
  98. char txpri, rxpri;
  99. {
  100.     int s;
  101.     char rc;
  102.     short xb[3];
  103.     SOCKADDR *sa = (SOCKADDR *)malloc(sizeof(SOCKADDR)+256);
  104.     char *dirstr = getenv("DNETDIR") ? getenv("DNETDIR") : "";
  105.  
  106.     if (rxpri < -127)
  107.     rxpri = -127;
  108.     if (rxpri > 126)
  109.     rxpri = 126;
  110.     if (txpri < -127)
  111.     txpri = -127;
  112.     if (txpri > 126)
  113.     txpri = 126;
  114.  
  115.     if (host == NULL)
  116.     host = (getenv("DNETHOST")) ? getenv("DNETHOST"):"3";
  117.  
  118.     sa->sa_family = AF_UNIX;
  119.     sprintf(sa->sa_data, "%s%s%s", dirstr, "DNET.", host);
  120.  
  121.     s = socket(PF_UNIX, SOCK_STREAM, 0);
  122.     fcntl(s, F_SETOWN, getpid());
  123.     if (connect(s, sa, sizeof(sa->sa_family) + strlen(sa->sa_data)) < 0) {
  124.     close(s);
  125.     free(sa);
  126.     return(-1);
  127.     }
  128.     free(sa);
  129.     xb[0] = port;
  130.     ((char *)&xb[1])[0] = txpri;
  131.     ((char *)&xb[1])[1] = rxpri;
  132.     write(s, xb, 4);
  133.     if (read(s, &rc, 1) == 1 && rc == 0)
  134.     return(s);
  135.     close(s);
  136.     return(-1);
  137. }
  138.  
  139. DEof(fd)
  140. {
  141.     char dummy;
  142.  
  143.     shutdown(fd, 1);
  144.     write(fd, &dummy, 0);
  145. }
  146.  
  147. gwrite(fd, buf, bytes)
  148. char *buf;
  149. {
  150.     int n;
  151.     int orig = bytes;
  152.     extern int errno;
  153.     while (bytes) {
  154.     n = write(fd, buf, bytes);
  155.     if (n > 0) {
  156.         bytes -= n;
  157.         buf += n;
  158.         continue;
  159.     }
  160.     if (n < 0) {
  161.         if (errno == EINTR)
  162.         continue;
  163.         if (errno == EWOULDBLOCK) {
  164.         int wm = 1 << fd;
  165.         int em = 1 << fd;
  166.         if (select(fd+1, NULL, &wm, &em, NULL) < 0)
  167.             continue;
  168.         if (wm)
  169.             continue;
  170.         }
  171.         return(orig - bytes);
  172.     }
  173.     }
  174.     return(orig);
  175. }
  176.  
  177. gread(fd, buf, bytes)
  178. char *buf;
  179. {
  180.     int n;
  181.     int orig = bytes;
  182.     extern int errno;
  183.     while (bytes) {
  184.     n = read(fd, buf, bytes);
  185.     if (n > 0) {
  186.         bytes -= n;
  187.         buf += n;
  188.         break;
  189.     }
  190.     if (n < 0) {
  191.         if (errno == EINTR)
  192.         continue;
  193.         if (errno == EWOULDBLOCK) {
  194.         int rm = 1 << fd;
  195.         int em = 1 << fd;
  196.         if (select(fd+1, &rm, NULL, &em, NULL) < 0)
  197.             continue;
  198.         if (rm)
  199.             continue;
  200.         }
  201.         return(orig - bytes);
  202.     }
  203.     if (n == 0)
  204.         break;
  205.     }
  206.     return(orig - bytes);
  207. }
  208.  
  209. ggread(fd, buf, bytes)
  210. char *buf;
  211. {
  212.     int n;
  213.     int ttl = 0;
  214.     while (bytes) {
  215.     n = gread(fd, buf, bytes);
  216.     if (n > 0) {
  217.         bytes -= n;
  218.         buf += n;
  219.         ttl += n;
  220.         continue;
  221.     }
  222.     return(-1);
  223.     }
  224.     return(ttl);
  225. }
  226.  
  227. /*
  228.  *    Convert to and from 68000 longword format.  Of course, it really
  229.  *    doesn't matter what format you use, just as long as it is defined.
  230.  */
  231.  
  232. ntohl68(n)
  233. ulong n;
  234. {
  235.     return(
  236.     (((ubyte *)&n)[0] << 24)|
  237.     (((ubyte *)&n)[1] << 16)|
  238.     (((ubyte *)&n)[2] << 8)|
  239.     (((ubyte *)&n)[3])
  240.     );
  241. }
  242.  
  243. htonl68(n)
  244. ulong n;
  245. {
  246.     ulong v;
  247.     ((ubyte *)&v)[0] = n >> 24;
  248.     ((ubyte *)&v)[1] = n >> 16;
  249.     ((ubyte *)&v)[2] = n >> 8;
  250.     ((ubyte *)&v)[3] = n;
  251.     return(v);
  252. }
  253.  
  254.  
  255. DoOption(ac, av, ops, args)
  256. short ac;
  257. char *av[];
  258. char *ops;
  259. long args;
  260. {
  261.     register short i;
  262.     short j;
  263.  
  264.     for (i = j = 1; i < ac; ++i) {
  265.     register char *ptr = av[i];
  266.     if (*ptr != '-') {
  267.         av[j++] = av[i];
  268.         continue;
  269.     }
  270.     while (*++ptr) {
  271.         register char *op;
  272.         long **ap = (long **)&args;
  273.         short isshort;
  274.  
  275.         for (op = ops; *op && *op != *ptr;) {
  276.         if (*op == *ptr)
  277.             break;
  278.         if (*++op == '%') {
  279.             while (*op && *op != 's' && *op != 'd')
  280.             ++op;
  281.             if (*op)
  282.             ++op;
  283.         }
  284.         if (*op == ',')     /*  optional ,  */
  285.             ++op;
  286.         ++ap;
  287.         }
  288.         if (*op == 0)
  289.         return(-1);
  290.         if (op[1] != '%') {
  291.         *(short *)*ap = 1;
  292.         ++ap;
  293.         continue;
  294.         }
  295.         op += 2;
  296.         isshort = 1;
  297.         while (*op && *op != 's' && *op != 'd') {
  298.         switch(*op) {
  299.         case 'h':
  300.             isshort = 1;
  301.             break;
  302.         case 'l':
  303.             isshort = 0;
  304.             break;
  305.         default:
  306.             return(-1);
  307.         }
  308.         ++op;
  309.         }
  310.         switch(*op) {
  311.         case 's':
  312.         if (ptr[1]) {
  313.             *(char **)*ap = ptr + 1;
  314.             ptr = "\0";
  315.         } else {
  316.             *(char **)*ap = av[++i];
  317.         }
  318.         break;
  319.         case 'd':
  320.         if (isshort)
  321.             *(short *)*ap = atoi(++ptr);
  322.         else
  323.             *(long *)*ap = atoi(++ptr);
  324.         while (*ptr >= '0' && *ptr <= '9')
  325.             ++ptr;
  326.         break;
  327.         default:
  328.         return(-1);
  329.         }
  330.     }
  331.     }
  332.     return(j);
  333. }
  334.  
  335. elog(how, ctl, arg)
  336. char *ctl;
  337. long arg;
  338. {
  339.     char *dir = getenv("DNETDIR");
  340.     FILE *fi;
  341.     char buf[256];
  342.     long dtime;
  343.  
  344.     time(&dtime);
  345.  
  346.     if (!dir)
  347.     dir = "";
  348.     sprintf(buf, "%s%s", dir, "DNET.LOG");
  349.     if (fi = fopen(buf, "a")) {
  350.     strcpy(buf, ctime(&dtime));
  351.     buf[strlen(buf)-1] = 0;
  352.     fprintf(fi, "%s ", buf);
  353.     fprintf(fi, ctl, arg);
  354.     putc('\n', fi);
  355.     fclose(fi);
  356.     }
  357.     if (how == EFATAL)
  358.     exit(1);
  359. }
  360.  
  361.