/* * DNETLIB.C * * DNET (c)Copyright 1988, Matthew Dillon, All Rights Reserved * * Library Interface for DNET. */ #include #include #include #include #include #include #ifdef O_CREAT #include #endif extern char *getenv(); typedef unsigned short uword; typedef unsigned long ulong; typedef unsigned char ubyte; typedef struct sockaddr SOCKADDR; typedef struct { int s; uword port; } CHANN; #define NAMELEN sizeof(".PORT.XXXXX") #define NAMEPAT "%s.PORT.%ld" CHANN * DListen(port) uword port; { CHANN *chan; int s; SOCKADDR *sa = (SOCKADDR *)malloc(sizeof(SOCKADDR)+256); char *dirstr = getenv("DNETDIR") ? getenv("DNETDIR") : ""; sprintf(sa->sa_data, NAMEPAT, dirstr, port); sa->sa_family = AF_UNIX; unlink(sa->sa_data); s = socket(PF_UNIX, SOCK_STREAM, 0); fcntl(s, F_SETOWN, getpid()); if (bind(s, sa, sizeof(*sa)-sizeof(sa->sa_data)+strlen(sa->sa_data)) < 0) { close(s); free(sa); return(NULL); } if (listen(s, 5) < 0) { close(s); unlink(sa->sa_data); free(sa); return(NULL); } chan = (CHANN *)malloc(sizeof(CHANN)); chan->s = s; chan->port = port; free(sa); return(chan); } DUnListen(chan) CHANN *chan; { char buf[32]; close(chan->s); sprintf(buf, NAMEPAT, chan->port); unlink(buf); free(chan); } DAccept(chan) CHANN *chan; { SOCKADDR sa; int addrlen = sizeof(sa); int fd; fd = accept(chan->s, &sa, &addrlen); return(fd); } DOpen(host, port, txpri, rxpri) char *host; uword port; char txpri, rxpri; { int s; char rc; short xb[3]; SOCKADDR *sa = (SOCKADDR *)malloc(sizeof(SOCKADDR)+256); char *dirstr = getenv("DNETDIR") ? getenv("DNETDIR") : ""; if (rxpri < -127) rxpri = -127; if (rxpri > 126) rxpri = 126; if (txpri < -127) txpri = -127; if (txpri > 126) txpri = 126; if (host == NULL) host = (getenv("DNETHOST")) ? getenv("DNETHOST"):""; sa->sa_family = AF_INET; sprintf(sa->sa_data, "%s%s%s", dirstr, "DNET.", host); s = socket(PF_UNIX, SOCK_STREAM, 0); fcntl(s, F_SETOWN, getpid()); if (connect(s, sa, sizeof(*sa)-sizeof(sa->sa_data)+ strlen(sa->sa_data))<0) { close(s); free(sa); return(-1); } free(sa); xb[0] = port; ((char *)&xb[1])[0] = txpri; ((char *)&xb[1])[1] = rxpri; write(s, xb, 4); if (read(s, &rc, 1) == 1 && rc == 0) return(s); close(s); return(-1); } DEof(fd) { char dummy; shutdown(fd, 1); write(fd, &dummy, 0); } gwrite(fd, buf, bytes) char *buf; { int n; int orig = bytes; extern int errno; while (bytes) { n = write(fd, buf, bytes); if (n > 0) { bytes -= n; buf += n; continue; } if (n < 0) { if (errno == EINTR) continue; if (errno == EWOULDBLOCK) { int wm = 1 << fd; int em = 1 << fd; if (select(fd+1, NULL, &wm, &em, NULL) < 0) continue; if (wm) continue; } return(orig - bytes); } } return(orig); } gread(fd, buf, bytes) char *buf; { int n; int orig = bytes; extern int errno; while (bytes) { n = read(fd, buf, bytes); if (n > 0) { bytes -= n; buf += n; break; } if (n < 0) { if (errno == EINTR) continue; if (errno == EWOULDBLOCK) { int rm = 1 << fd; int em = 1 << fd; if (select(fd+1, &rm, NULL, &em, NULL) < 0) continue; if (rm) continue; } return(orig - bytes); } if (n == 0) break; } return(orig - bytes); } ggread(fd, buf, bytes) char *buf; { int n; int ttl = 0; while (bytes) { n = gread(fd, buf, bytes); if (n > 0) { bytes -= n; buf += n; ttl += n; continue; } return(-1); } return(ttl); } /* * Convert to and from 68000 longword format. Of course, it really * doesn't matter what format you use, just as long as it is defined. */ ntohl68(n) ulong n; { return( (((ubyte *)&n)[0] << 24)| (((ubyte *)&n)[1] << 16)| (((ubyte *)&n)[2] << 8)| (((ubyte *)&n)[3]) ); } htonl68(n) ulong n; { ulong v; ((ubyte *)&v)[0] = n >> 24; ((ubyte *)&v)[1] = n >> 16; ((ubyte *)&v)[2] = n >> 8; ((ubyte *)&v)[3] = n; return(v); }