diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/ape/lib/net |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/ape/lib/net')
-rwxr-xr-x | sys/src/ape/lib/net/announce.c | 222 | ||||
-rwxr-xr-x | sys/src/ape/lib/net/dial.c | 128 | ||||
-rwxr-xr-x | sys/src/ape/lib/net/hangup.c | 16 | ||||
-rwxr-xr-x | sys/src/ape/lib/net/mkfile | 13 | ||||
-rwxr-xr-x | sys/src/ape/lib/net/netmkaddr.c | 56 |
5 files changed, 435 insertions, 0 deletions
diff --git a/sys/src/ape/lib/net/announce.c b/sys/src/ape/lib/net/announce.c new file mode 100755 index 000000000..807239f5d --- /dev/null +++ b/sys/src/ape/lib/net/announce.c @@ -0,0 +1,222 @@ +#include <stdlib.h> +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include <libnet.h> + +#define NAMELEN 28 + +static int nettrans(char*, char*, int na, char*, int); + +/* + * announce a network service. + */ +int +announce(char *addr, char *dir) +{ + int ctl, n, m; + char buf[3*NAMELEN]; + char buf2[3*NAMELEN]; + char netdir[2*NAMELEN]; + char naddr[3*NAMELEN]; + char *cp; + + /* + * translate the address + */ + if(nettrans(addr, naddr, sizeof(naddr), netdir, sizeof(netdir)) < 0) + return -1; + + /* + * get a control channel + */ + ctl = open(netdir, O_RDWR); + if(ctl<0) + return -1; + cp = strrchr(netdir, '/'); + *cp = 0; + + /* + * find out which line we have + */ + n = sprintf(buf, "%.*s/", 2*NAMELEN+1, netdir); + m = read(ctl, &buf[n], sizeof(buf)-n-1); + if(n<=0){ + close(ctl); + return -1; + } + buf[n+m] = 0; + + /* + * make the call + */ + n = sprintf(buf2, "announce %.*s", 2*NAMELEN, naddr); + if(write(ctl, buf2, n)!=n){ + close(ctl); + return -1; + } + + /* + * return directory etc. + */ + if(dir) + strcpy(dir, buf); + return ctl; +} + +/* + * listen for an incoming call + */ +int +listen(char *dir, char *newdir) +{ + int ctl, n, m; + char buf[3*NAMELEN]; + char *cp; + + /* + * open listen, wait for a call + */ + sprintf(buf, "%.*s/listen", 2*NAMELEN+1, dir); + ctl = open(buf, O_RDWR); + if(ctl < 0) + return -1; + + /* + * find out which line we have + */ + strcpy(buf, dir); + cp = strrchr(buf, '/'); + *++cp = 0; + n = cp-buf; + m = read(ctl, cp, sizeof(buf) - n - 1); + if(n<=0){ + close(ctl); + return -1; + } + buf[n+m] = 0; + + /* + * return directory etc. + */ + if(newdir) + strcpy(newdir, buf); + return ctl; + +} + +/* + * accept a call, return an fd to the open data file + */ +int +accept(int ctl, char *dir) +{ + char buf[128]; + char *num; + long n; + + num = strrchr(dir, '/'); + if(num == 0) + num = dir; + else + num++; + + sprintf(buf, "accept %s", num); + n = strlen(buf); + write(ctl, buf, n); /* ignore return value, netowrk might not need accepts */ + + sprintf(buf, "%s/data", dir); + return open(buf, O_RDWR); +} + +/* + * reject a call, tell device the reason for the rejection + */ +int +reject(int ctl, char *dir, char *cause) +{ + char buf[128]; + char *num; + long n; + + num = strrchr(dir, '/'); + if(num == 0) + num = dir; + else + num++; + sprintf(buf, "reject %s %s", num, cause); + n = strlen(buf); + if(write(ctl, buf, n) != n) + return -1; + return 0; +} + +/* + * perform the identity translation (in case we can't reach cs) + */ +static int +identtrans(char *addr, char *naddr, int na, char *file, int nf) +{ + char reply[4*NAMELEN]; + char *p; + + USED(nf); + + /* parse the network */ + strncpy(reply, addr, sizeof(reply)); + reply[sizeof(reply)-1] = 0; + p = strchr(addr, '!'); + if(p) + *p++ = 0; + + sprintf(file, "/net/%.*s/clone", na - sizeof("/net//clone"), reply); + strncpy(naddr, p, na); + naddr[na-1] = 0; + + return 1; +} + +/* + * call up the connection server and get a translation + */ +static int +nettrans(char *addr, char *naddr, int na, char *file, int nf) +{ + int fd; + char reply[4*NAMELEN]; + char *cp; + long n; + + /* + * ask the connection server + */ + fd = open("/net/cs", O_RDWR); + if(fd < 0) + return identtrans(addr, naddr, na, file, nf); + if(write(fd, addr, strlen(addr)) < 0){ + close(fd); + return -1; + } + lseek(fd, 0, 0); + n = read(fd, reply, sizeof(reply)-1); + close(fd); + if(n <= 0) + return -1; + reply[n] = 0; + + /* + * parse the reply + */ + cp = strchr(reply, ' '); + if(cp == 0) + return -1; + *cp++ = 0; + strncpy(naddr, cp, na); + naddr[na-1] = 0; + strncpy(file, reply, nf); + file[nf-1] = 0; + return 0; +} diff --git a/sys/src/ape/lib/net/dial.c b/sys/src/ape/lib/net/dial.c new file mode 100755 index 000000000..712c6148f --- /dev/null +++ b/sys/src/ape/lib/net/dial.c @@ -0,0 +1,128 @@ +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <fcntl.h> +#include <stdio.h> +#include <unistd.h> +#include <libnet.h> + +#define NAMELEN 28 + +static int +call(char *clone, char *dest, int *cfdp, char *dir, char *local) +{ + int fd, cfd; + int n; + char name[3*NAMELEN+5]; + char data[3*NAMELEN+10]; + char *p; + + cfd = open(clone, O_RDWR); + if(cfd < 0) + return -1; + + /* get directory name */ + n = read(cfd, name, sizeof(name)-1); + if(n < 0){ + close(cfd); + return -1; + } + name[n] = 0; + p = strrchr(clone, '/'); + *p = 0; + if(dir) + sprintf(dir, "%.*s/%.*s", 2*NAMELEN+1, clone, NAMELEN, name); + sprintf(data, "%.*s/%.*s/data", 2*NAMELEN+1, clone, NAMELEN, name); + + /* set local side (port number, for example) if we need to */ + if(local) + sprintf(name, "connect %.*s %.*s", 2*NAMELEN, dest, NAMELEN, local); + else + sprintf(name, "connect %.*s", 2*NAMELEN, dest); + + /* connect */ + if(write(cfd, name, strlen(name)) < 0){ + close(cfd); + return -1; + } + + /* open data connection */ + fd = open(data, O_RDWR); + if(fd < 0){ + close(cfd); + return -1; + } + if(cfdp) + *cfdp = cfd; + else + close(cfd); + return fd; +} + +int +dial(char *dest, char *local, char *dir, int *cfdp) +{ + char net[128]; + char netdir[128], csname[NETPATHLEN], *slp; + char clone[NAMELEN+12]; + char *p; + int n; + int fd; + int rv; + + /* go for a standard form net!... */ + p = strchr(dest, '!'); + if(p == 0){ + sprintf(net, "net!%.*s", sizeof(net)-5, dest); + } else { + strncpy(net, dest, sizeof(net)-1); + net[sizeof(net)-1] = 0; + } + + slp = strrchr(net, '/'); + if (slp != 0) { + *slp++ = '\0'; + strcpy(netdir, net); + memmove(net, slp, strlen(slp)+1); + } else + strcpy(netdir, "/net"); + + + /* call the connection server */ + sprintf(csname, "%s/cs", netdir); + fd = open(csname, O_RDWR); + if(fd < 0){ + /* no connection server, don't translate */ + p = strchr(net, '!'); + *p++ = 0; + sprintf(clone, "%s/%s/clone", netdir, net); + return call(clone, p, cfdp, dir, local); + } + + /* + * send dest to connection to translate + */ + if(write(fd, net, strlen(net)) < 0){ + close(fd); + return -1; + } + + /* + * loop through each address from the connection server till + * we get one that works. + */ + rv = -1; + lseek(fd, 0, 0); + while((n = read(fd, net, sizeof(net) - 1)) > 0){ + net[n] = 0; + p = strchr(net, ' '); + if(p == 0) + continue; + *p++ = 0; + rv = call(net, p, cfdp, dir, local); + if(rv >= 0) + break; + } + close(fd); + return rv; +} diff --git a/sys/src/ape/lib/net/hangup.c b/sys/src/ape/lib/net/hangup.c new file mode 100755 index 000000000..920ac1cdd --- /dev/null +++ b/sys/src/ape/lib/net/hangup.c @@ -0,0 +1,16 @@ +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <fcntl.h> +#include <stdio.h> +#include <unistd.h> +#include <libnet.h> + +/* + * force a connection to hangup + */ +int +hangup(int ctl) +{ + return write(ctl, "hangup", sizeof("hangup")-1) != sizeof("hangup")-1; +} diff --git a/sys/src/ape/lib/net/mkfile b/sys/src/ape/lib/net/mkfile new file mode 100755 index 000000000..49539c079 --- /dev/null +++ b/sys/src/ape/lib/net/mkfile @@ -0,0 +1,13 @@ +APE=/sys/src/ape +<$APE/config + +LIB=/$objtype/lib/ape/libnet.a +OFILES=dial.$O\ + announce.$O\ + netmkaddr.$O\ + hangup.$O\ + + +</sys/src/cmd/mksyslib + +CFLAGS=-c -D_POSIX_SOURCE -D_RESEARCH_SOURCE -D_NET_EXTENSION diff --git a/sys/src/ape/lib/net/netmkaddr.c b/sys/src/ape/lib/net/netmkaddr.c new file mode 100755 index 000000000..52b9710a0 --- /dev/null +++ b/sys/src/ape/lib/net/netmkaddr.c @@ -0,0 +1,56 @@ +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <fcntl.h> +#include <stdio.h> +#include <unistd.h> +#include <libnet.h> + +/* + * make an address, add the defaults + */ +char * +netmkaddr(char *linear, char *defnet, char *defsrv) +{ + static char addr[256]; + char *cp; + + /* + * dump network name + */ + cp = strchr(linear, '!'); + if(cp == 0){ + if(defnet==0){ + if(defsrv) + snprintf(addr, sizeof(addr), "net!%s!%s", + linear, defsrv); + else + snprintf(addr, sizeof(addr), "net!%s", linear); + } + else { + if(defsrv) + snprintf(addr, sizeof(addr), "%s!%s!%s", defnet, + linear, defsrv); + else + snprintf(addr, sizeof(addr), "%s!%s", defnet, + linear); + } + return addr; + } + + /* + * if there is already a service, use it + */ + cp = strchr(cp+1, '!'); + if(cp) + return linear; + + /* + * add default service + */ + if(defsrv == 0) + return linear; + snprintf(addr, sizeof(addr), "%s!%s", linear, defsrv); + + return addr; +} |