commit df407fd8cde2c2a9c19969fb40328f94ff1b048e
parent f137735249b8fe732de47ae5ccbc92de12953a84
Author: Anselm R. Garbe <garbeam@wmii.de>
Date: Mon, 30 Jan 2006 20:08:58 +0200
removed old libixp crap, now several things are broken and will settle after a while
Diffstat:
| Makefile | | | 2 | +- |
| cmd/Makefile | | | 22 | +++++----------------- |
| cmd/wm/client.c | | | 4 | ++-- |
| cmd/wm/wm.c | | | 12 | ++++++------ |
| cmd/wm/wm.h | | | 74 | +++++++++++++++++--------------------------------------------------------- |
| cmd/wmiibar.c | | | 2 | +- |
| cmd/wmiir.c | | | 377 | ++++++++++++++++++++++++++++++++++++++++--------------------------------------- |
| cmd/wmiir2.c | | | 236 | ------------------------------------------------------------------------------- |
| libixp/Makefile | | | 5 | ++--- |
| libixp/client.c | | | 400 | ++++++++++++++++++++++++++++++------------------------------------------------- |
| libixp/convert.c | | | 197 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| libixp/ixp.h | | | 413 | +++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------- |
| libixp/message.c | | | 431 | +++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------- |
| libixp/ramfs.c | | | 297 | ------------------------------------------------------------------------------- |
| libixp/server.c | | | 453 | ++++++++----------------------------------------------------------------------- |
| libixp/socket.c | | | 204 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| libixp/transport.c | | | 81 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| libixp2/Makefile | | | 25 | ------------------------- |
| libixp2/client.c | | | 194 | ------------------------------------------------------------------------------- |
| libixp2/convert.c | | | 197 | ------------------------------------------------------------------------------- |
| libixp2/ixp.h | | | 289 | ------------------------------------------------------------------------------ |
| libixp2/message.c | | | 317 | ------------------------------------------------------------------------------- |
| libixp2/server.c | | | 73 | ------------------------------------------------------------------------- |
| libixp2/socket.c | | | 204 | ------------------------------------------------------------------------------- |
| libixp2/transport.c | | | 81 | ------------------------------------------------------------------------------- |
| libwmii/Makefile | | | 2 | +- |
| libwmii/ixputil.c | | | 98 | ------------------------------------------------------------------------------- |
| libwmii/wmii.h | | | 6 | ------ |
28 files changed, 1457 insertions(+), 3239 deletions(-)
diff --git a/Makefile b/Makefile
@@ -3,7 +3,7 @@
include config.mk
-SUBDIRS = libcext liblitz libixp libixp2 libwmii cmd
+SUBDIRS = libcext liblitz libixp libwmii cmd
BIN = cmd/wm/wmii cmd/wm/wmiiwm cmd/wmiibar cmd/wmiifs \
cmd/wmiikeys cmd/wmiimenu cmd/wmiiplumb cmd/wmiir cmd/wmiir2 cmd/wmiiwarp
diff --git a/cmd/Makefile b/cmd/Makefile
@@ -5,9 +5,7 @@ include ../config.mk
CFLAGS += -I../liblitz -I../libixp -I../libwmii -I../libcext
LDFLAGS += -L../liblitz -llitz -L../libixp -lixp \
- -L../libwmii -lwmii -L../libcext -lcext
-LDFLAGS2 += ${LIBS} -L../liblitz -llitz -L../libixp2 -lixp \
- -L../libwmii -lwmii -L../libcext -lcext
+ -L../libwmii -lwmii -L../libcext -lcext
SRC_bar = wmiibar.c
OBJ_bar = ${SRC_bar:.c=.o}
@@ -15,9 +13,6 @@ OBJ_bar = ${SRC_bar:.c=.o}
SRC_menu = wmiimenu.c
OBJ_menu = ${SRC_menu:.c=.o}
-SRC_r2 = wmiir2.c
-OBJ_r2 = ${SRC_r2:.c=.o}
-
SRC_r = wmiir.c
OBJ_r = ${SRC_r:.c=.o}
@@ -33,7 +28,8 @@ OBJ_plumb = ${SRC_plumb:.c=.o}
SRC_warp = wmiiwarp.c
OBJ_warp = ${SRC_warp:.c=.o}
-all: wmiibar wmiimenu wmiir wmiir2 wmiifs wmiikeys wmiiplumb wmiiwarp
+#all: wmiibar wmiimenu wmiir wmiifs wmiikeys wmiiplumb wmiiwarp
+all: wmiibar wmiir wmiiplumb wmiiwarp
@echo built wmii commands
.c.o:
@@ -42,9 +38,9 @@ all: wmiibar wmiimenu wmiir wmiir2 wmiifs wmiikeys wmiiplumb wmiiwarp
wmiibar: ${OBJ_bar}
@echo LD $@
- @${CC} -o $@ ${OBJ_bar} ${LDFLAGS2}
+ @${CC} -o $@ ${OBJ_bar} ${LDFLAGS}
# Solaris
-# @${CC} -o $@ ${OBJ_bar2} ${LDFLAGS2} -lsocket
+# @${CC} -o $@ ${OBJ_bar} ${LDFLAGS} -lsocket
wmiimenu: ${OBJ_menu}
@echo LD $@
@@ -52,14 +48,6 @@ wmiimenu: ${OBJ_menu}
# Solaris
# @${CC} -o $@ ${OBJ_menu} ${LDFLAGS} -lsocket
-wmiir2: ${OBJ_r2}
- @echo LD $@
- @${CC} -o $@ ${OBJ_r2} -g -static -L${PREFIX}/lib -L/usr/lib -lc \
- -L../libixp2 -lixp -L../libcext -lcext
-# Solaris
-# @${CC} -o $@ ${OBJ_r2} -g -static -L${PREFIX}/lib -L/usr/lib -lc \
-# -L../libixp2 -lixp -L../libcext -lcext -lsocket
-
wmiir: ${OBJ_r}
@echo LD $@
@${CC} -o $@ ${OBJ_r} -g -static -L${PREFIX}/lib -L/usr/lib -lc \
diff --git a/cmd/wm/client.c b/cmd/wm/client.c
@@ -291,7 +291,7 @@ draw_client(Client *c)
XRectangle notch;
d.drawable = c->frame.win;
- d.font = font;
+ d.xfont = xfont;
d.gc = c->frame.gc;
if(c == sel_client()) {
@@ -476,7 +476,7 @@ unsigned int
tab_height(Client * c)
{
if(blitz_strtonum(c->file[C_TAB]->content, 0, 1))
- return font->ascent + font->descent + 4;
+ return xfont->ascent + xfont->descent + 4;
return 0;
}
diff --git a/cmd/wm/wm.c b/cmd/wm/wm.c
@@ -8,7 +8,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/wait.h>
-#include <X11/cursorfont.h>
+#include <X11/cursorxfont.h>
#include <X11/Xproto.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
@@ -177,7 +177,7 @@ draw_pager()
th = ((double) tw / rect.width) * rect.height;
d.drawable = transient;
d.gc = gc_transient;
- d.font = font;
+ d.xfont = xfont;
i = 0;
for(ir = 0; ir < rows; ir++) {
for(ic = 0; ic < cols; ic++) {
@@ -563,8 +563,8 @@ handle_after_write(IXPServer * s, File * f)
&color_xor, &color_xor);
XSetForeground(dpy, gc_xor, color_xor.pixel);
} else if(f == def[WM_FONT]) {
- XFreeFont(dpy, font);
- font = blitz_getfont(dpy, def[WM_FONT]->content);
+ XFreeFont(dpy, xfont);
+ xfont = blitz_getxfont(dpy, def[WM_FONT]->content);
}
check_event(0);
}
@@ -625,7 +625,7 @@ init_default()
BLITZ_NORM_FG_COLOR);
def[WM_NORM_BORDER_COLOR] = wmii_create_ixpfile(ixps, "/default/nstyle/bordercolor",
BLITZ_NORM_BORDER_COLOR);
- def[WM_FONT] = wmii_create_ixpfile(ixps, "/default/font", BLITZ_FONT);
+ def[WM_FONT] = wmii_create_ixpfile(ixps, "/default/xfont", BLITZ_FONT);
def[WM_FONT]->after_write = handle_after_write;
def[WM_SNAP_VALUE] = wmii_create_ixpfile(ixps, "/default/snapvalue", "20"); /* 0..1000 */
def[WM_BORDER] = wmii_create_ixpfile(ixps, "/default/border", "1");
@@ -803,7 +803,7 @@ main(int argc, char *argv[])
init_atoms();
init_cursors();
init_default();
- font = blitz_getfont(dpy, def[WM_FONT]->content);
+ xfont = blitz_getxfont(dpy, def[WM_FONT]->content);
wmii_init_lock_modifiers(dpy, &valid_mask, &num_lock_mask);
init_screen();
scan_wins();
diff --git a/cmd/wm/wm.h b/cmd/wm/wm.h
@@ -9,56 +9,6 @@
#include "wmii.h"
-/* array indexes of page file pointers */
-enum {
- P_PREFIX,
- P_NAME,
- P_CLIENT_PREFIX,
- P_SEL_PREFIX,
- P_CTL,
- P_LAST
-};
-
-/* array indexes of frame file pointers */
-enum {
- C_PREFIX,
- C_NAME,
- C_GEOMETRY,
- C_BORDER,
- C_TAB,
- C_HANDLE_INC,
- C_CTL,
- C_LAST
-};
-
-/* array indexes of wm file pointers */
-enum {
- WM_CTL,
- WM_TRANS_COLOR,
- WM_COLUMN_GEOMETRY,
- WM_SEL_BG_COLOR,
- WM_SEL_BORDER_COLOR,
- WM_SEL_FG_COLOR,
- WM_NORM_BG_COLOR,
- WM_NORM_BORDER_COLOR,
- WM_NORM_FG_COLOR,
- WM_FONT,
- WM_BORDER,
- WM_TAB,
- WM_HANDLE_INC,
- WM_SNAP_VALUE,
- WM_DETACHED_PREFIX,
- WM_SEL_PAGE,
- WM_EVENT_PAGE_UPDATE,
- WM_EVENT_CLIENT_UPDATE,
- WM_EVENT_B1PRESS,
- WM_EVENT_B2PRESS,
- WM_EVENT_B3PRESS,
- WM_EVENT_B4PRESS,
- WM_EVENT_B5PRESS,
- WM_LAST
-};
-
/* array indexes of EWMH window properties */
/* TODO: set / react */
enum {
@@ -96,7 +46,6 @@ struct Page {
size_t sel_column;
Bool is_column;
XRectangle rect_column;
- File *file[P_LAST];
};
struct Client {
@@ -104,6 +53,7 @@ struct Client {
int proto;
unsigned int border;
unsigned int ignore_unmap;
+ Bool handle_inc;
Bool destroyed;
Bool maximized;
Bool attached;
@@ -119,8 +69,8 @@ struct Client {
XRectangle revert;
GC gc;
Cursor cursor;
+ Bool title;
} frame;
- File *file[C_LAST];
};
/* global variables */
@@ -140,11 +90,22 @@ int screen;
Window root;
Window transient; /* pager / attach */
XRectangle rect;
-XFontStruct *font;
+XFontStruct *xfont;
XColor color_xor;
GC gc_xor;
GC gc_transient;
+/* default values */
+typedef struct {
+ char xorcolor[24];
+ char selcolor[24];
+ char normcolor[24];
+ char font[24];
+ unsigned int border;
+ unsigned int title;
+ unsigned int snap;
+} Default def;
+
Atom wm_state; /* TODO: Maybe replace with wm_atoms[WM_ATOM_COUNT]? */
Atom wm_change_state;
Atom wm_protocols;
@@ -165,9 +126,6 @@ Cursor ne_cursor;
Cursor sw_cursor;
Cursor se_cursor;
-/* default file pointers */
-File *def[WM_LAST];
-
unsigned int valid_mask, num_lock_mask;
@@ -222,12 +180,14 @@ void select_column(Client *c, char *arg);
void new_column(Page *p);
/* wm.c */
+/*
void invoke_wm_event(File * f);
void run_action(File * f, void *obj, Action * acttbl);
+*/
void scan_wins();
Client *win_to_client(Window w);
int win_proto(Window w);
int win_state(Window w);
-void handle_after_write(IXPServer * s, File * f);
+/*void handle_after_write(IXPServer * s, File * f);*/
void detach(Client * f, int client_destroyed);
void set_client_state(Client * c, int state);
diff --git a/cmd/wmiibar.c b/cmd/wmiibar.c
@@ -18,7 +18,7 @@
#include <X11/Xutil.h>
#include <sys/socket.h>
-#include "../libixp2/ixp.h"
+#include "ixp.h"
#include "blitz.h"
/*
diff --git a/cmd/wmiir.c b/cmd/wmiir.c
@@ -6,11 +6,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+#include <dirent.h>
#include "ixp.h"
-static IXPClient *c;
-static int exit_code = 0;
+#include <cext.h>
+
+static IXPClient c = { 0 };
static char *version[] = {
"wmiir - window manager improved remote - " VERSION "\n"
@@ -21,211 +24,213 @@ static void
usage()
{
fprintf(stderr, "%s",
- "usage: wmiir [-s <socket file>] [-v] <action> <action_arg> [...]\n"
- " -s socket file (default: $WMIIR_SOCKET)\n"
- " -f read actions from stdin\n"
+ "usage: wmiir [-a <server address>] [-v] <command>\n"
+ " -a server address (default: $WMIIR_ADDRESS)\n"
" -v version info\n"
- "actions:\n"
- " create <file> [<content>] -- creates and optionally writes content to a file\n"
- " write <file> <content> -- writes content to a file\n"
- " read <directory/file> -- reads file or directory contents\n"
- " remove <directory/file> -- removes file or directory, use with care!\n");
+ "valid commands:\n"
+ " create <file> -- creates file and writes data from stdin to file\n"
+ " read <file/dir> -- prints file/directory contents\n"
+ " write <file> -- writes data from stdin to file\n"
+ " remove <file> -- removes file\n");
exit(1);
}
static void
-perform(char *action, char *file, char *content)
+write_data(unsigned int fid)
{
- size_t out_len = 0;
- char output[2050];
- int crt, fd = -1;
-
- if(!action)
- return;
-
- crt = !strncmp(action, "create", 7);
- if(!strncmp(action, "write", 6) || crt) {
- if(!file)
- return;
- /* create file first */
- if(crt) {
- c->create(c, file);
- if(c->errstr) {
- fprintf(stderr, "wmiir: error: create %s: %s\n", file,
- c->errstr);
- exit_code = 1;
- return;
- }
- }
- if(!content)
- return;
- fd = c->open(c, file);
- if(c->errstr) {
- fprintf(stderr, "wmiir: error: open %s: %s\n", file,
- c->errstr);
- exit_code = 1;
- return;
- }
- c->write(c, fd, content, strlen(content));
- if(c->errstr) {
- fprintf(stderr, "wmiir: error: write %s: %s\n", file,
- c->errstr);
- exit_code = 1;
- if(!strncmp(c->errstr, DEAD_SERVER, strlen(DEAD_SERVER) + 1))
- return;
- }
- } else if(!strncmp(action, "read", 5)) {
- if(!file)
- return;
- fd = c->open(c, file);
- if(c->errstr) {
- fprintf(stderr, "wmiir: error: open %s: %s\n", file,
- c->errstr);
- exit_code = 1;
- return;
- }
- do {
- out_len = c->read(c, fd, output, 2048);
- if(c->errstr) {
- fprintf(stderr, "wmiir: error: read %s: %s\n", file,
- c->errstr);
- exit_code = 1;
- if(!strncmp
- (c->errstr, DEAD_SERVER, strlen(DEAD_SERVER) + 1))
- return;
- break;
- }
- output[out_len] = 0;
- fprintf(stdout, "%s", output);
- }
- while(out_len == 2048);
- fprintf(stdout, "%s", "\n");
- } else if(!strncmp(action, "remove", 7)) {
- if(!file)
- return;
- c->remove(c, file);
- if(c->errstr) {
- fprintf(stderr, "wmiir: error: remove %s: %s\n", file,
- c->errstr);
- exit_code = 1;
- return;
+ void *data = cext_emallocz(c.fcall.iounit);
+ unsigned long long offset = 0;
+ size_t len = 0;
+
+ while((len = read(0, data, c.fcall.iounit)) > 0) {
+ fprintf(stderr, "read=%d, bufsz=%d\n", len, c.fcall.iounit);
+ if(ixp_client_write
+ (&c, fid, offset, len, data) != len) {
+ fprintf(stderr, "wmiir: cannot write file: %s\n", c.errstr);
+ break;
}
+ offset += len;
}
- if(fd != -1) {
- c->close(c, fd);
- if(c->errstr) {
- fprintf(stderr, "wmiir: error: close %s: %s\n", file,
- c->errstr);
- exit_code = 1;
- return;
- }
+ free(data);
+}
+
+static int
+xcreate(char *file)
+{
+ unsigned int fid;
+ char *p = strrchr(file, '/');
+
+ fid = c.root_fid << 2;
+ /* walk to bottom-most directory */
+ *p = 0;
+ if(ixp_client_walk(&c, fid, file) == -1) {
+ fprintf(stderr, "wmiir: cannot walk to '%s': %s\n", file, c.errstr);
+ return -1;
+ }
+ /* create */
+ p++;
+ if(ixp_client_create(&c, fid, p, (unsigned int) 0xff, IXP_OWRITE) == -1) {
+ fprintf(stderr, "wmiir: cannot create file '%s': %s\n", p, c.errstr);
+ return -1;
}
+ write_data(fid);
+ return ixp_client_close(&c, fid);
+}
+
+static int
+xwrite(char *file)
+{
+
+ /* open */
+ unsigned int fid = c.root_fid << 2;
+ if(ixp_client_open(&c, fid, file, IXP_OWRITE) == -1) {
+ fprintf(stderr, "wmiir: cannot open file '%s': %s\n", file, c.errstr);
+ return -1;
+ }
+ write_data(fid);
+ return ixp_client_close(&c, fid);
+}
+
+static int
+comp(const void *s1, const void *s2)
+{
+ return strcmp(*(char **)s1, *(char **)s2);
+}
+
+static void
+xls(void *result, unsigned int msize)
+{
+ size_t n = 0, j = 0;
+ char buf[IXP_MAX_FLEN];
+ void *p = result;
+ char **dir;
+ static Stat stat, zerostat = { 0 };
+ do {
+ p = ixp_dec_stat(p, &stat);
+ n++;
+ }
+ while(p - result < msize);
+ dir = (char **)cext_emallocz(sizeof(char *) * n);
+ p = result;
+ do {
+ p = ixp_dec_stat(p, &stat);
+ if(stat.qid.type == IXP_QTDIR)
+ snprintf(buf, sizeof(buf), "%s/", stat.name);
+ else
+ snprintf(buf, sizeof(buf), "%s", stat.name);
+ dir[j++] = cext_estrdup(buf);
+ stat = zerostat;
+ }
+ while(p - result < msize);
+ qsort(dir, n, sizeof(char *), comp);
+ for(j = 0; j < n; j++) {
+ fprintf(stdout, "%s\n", dir[j]);
+ free(dir[j]);
+ }
+ free(dir);
+}
+
+static int
+xread(char *file)
+{
+ unsigned int fid = c.root_fid << 2;
+ int count, is_directory = 0;
+ static unsigned char result[IXP_MAX_MSG];
+ unsigned long long offset = 0;
+
+ /* open */
+ if(ixp_client_open(&c, fid, file, IXP_OREAD) == -1) {
+ fprintf(stderr, "wmiir: cannot open file '%s': %s\n", file, c.errstr);
+ return -1;
+ }
+ is_directory = !c.fcall.nwqid || (c.fcall.qid.type == IXP_QTDIR);
+
+ /* read */
+ while((count = ixp_client_read(&c, fid, offset, result, IXP_MAX_MSG)) > 0) {
+ if(is_directory)
+ xls(result, count);
+ else {
+ unsigned int i;
+ for(i = 0; i < count; i++)
+ fputc(result[i], stdout);
+ fflush(stdout);
+ }
+ offset += count;
+ }
+ if(count == -1) {
+ fprintf(stderr, "wmiir: cannot read file/directory '%s': %s\n", file, c.errstr);
+ return -1;
+ }
+ return ixp_client_close(&c, fid);
+}
+
+static int
+xremove(char *file)
+{
+ unsigned int fid;
+
+ /* remove */
+ fid = c.root_fid << 2;
+ if(ixp_client_remove(&c, fid, file) == -1) {
+ fprintf(stderr, "wmiir: cannot remove file '%s': %s\n", file, c.errstr);
+ return -1;
+ }
+ return 0;
}
int
main(int argc, char *argv[])
{
- int i = 0, read_stdin = 0;
- char line[4096], *p;
- char *sockfile = getenv("WMIIR_SOCKET");
+ int i = 0;
+ char *cmd, *file, *sockfile = getenv("WMIIR_ADDRESS");
/* command line args */
- if(argc > 1) {
- for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) {
- switch (argv[i][1]) {
- case 'v':
- fprintf(stderr, "%s", version[0]);
- exit(0);
- break;
- case 's':
- if(i + 1 < argc) {
- sockfile = argv[++i];
- } else {
- usage();
- }
- break;
- case 'f':
- read_stdin = 1;
- break;
- default:
- usage();
- break;
- }
- }
- }
- if((argc <= 1) || (!read_stdin && (i + 1) >= argc)) {
- fprintf(stderr, "%s", "wmiir: arguments: ");
- for(i = 1; i < argc; i++)
- fprintf(stderr, "%s, ", argv[i]);
- fprintf(stderr, "%s", "\n");
- usage();
- }
+ if(argc < 2)
+ usage();
+
+ for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) {
+ switch (argv[i][1]) {
+ case 'v':
+ fprintf(stderr, "%s", version[0]);
+ exit(0);
+ break;
+ case 'a':
+ if(i + 1 < argc)
+ sockfile = argv[++i];
+ else
+ usage();
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+ cmd = argv[argc - 2];
+ file = argv[argc - 1];
+
if(!sockfile) {
- fprintf(stderr, "%s",
- "wmiir: error: WMIIR_SOCKET environment not set\n");
+ fprintf(stderr, "%s", "wmiir: error: $WMIIR_ADDRESS not set\n");
usage();
}
/* open socket */
- if(!(c = init_ixp_client(sockfile))) {
- fprintf(stderr, "wmiir: cannot connect to server '%s'\n",
- sockfile);
+ if(ixp_client_init(&c, sockfile) == -1) {
+ fprintf(stderr, "wmiir: %s\n", c.errstr);
exit(1);
}
- if(read_stdin) {
- /* simple shell */
- char *action, *file, *content;
- while(fgets(line, 4096, stdin)) {
- p = line;
- while(*p != 0 && (*p == ' ' || *p == '\t'))
- p++;
- if(*p == 0)
- continue; /* empty line */
- if(strncmp(p, "create ", 7) &&
- strncmp(p, "write ", 6) &&
- strncmp(p, "read ", 5) && strncmp(p, "remove ", 7))
- continue;
-
- action = p;
- while(*p != 0 && *p != ' ' && *p != '\t' && *p != '\n')
- p++;
- if(*p == 0 || *p == '\n')
- continue; /* ignore bogus command */
- *p = 0;
- p++;
- while(*p != 0 && (*p == ' ' || *p == '\t'))
- p++;
- if(*p == 0)
- continue; /* ignore bogus command */
- file = p;
- while(*p != 0 && *p != ' ' && *p != '\t' && *p != '\n')
- p++;
- if(*p == 0 || *p == '\n') {
- content = 0;
- *p = 0;
- } else {
- *p = 0;
- p++;
- content = p;
- }
- if(file[0] == 0)
- continue;
- if(content) {
- static size_t len;
- if((len = strlen(content)))
- content[len - 1] = 0;
- }
- perform(action, file, content);
- if(c->errstr)
- fprintf(stderr, "wmiir: error: read %s: %s\n", file,
- c->errstr);
- }
- } else {
- perform(argv[i], argv[i + 1], (i + 2) < argc ? argv[i + 2] : 0);
- }
- if(c->errstr) {
- deinit_client(c);
- exit_code = 1;
- }
- return exit_code;
+ if(!strncmp(cmd, "create", 7))
+ xcreate(file);
+ else if(!strncmp(cmd, "write", 6))
+ xwrite(file);
+ else if(!strncmp(cmd, "read", 5))
+ xread(file);
+ else if(!strncmp(cmd, "remove", 7))
+ xremove(file);
+ else
+ usage();
+
+ /* close socket */
+ ixp_client_deinit(&c);
+
+ return 0;
}
diff --git a/cmd/wmiir2.c b/cmd/wmiir2.c
@@ -1,236 +0,0 @@
-/*
- * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <dirent.h>
-
-#include "../libixp2/ixp.h"
-
-#include <cext.h>
-
-static IXPClient c = { 0 };
-
-static char *version[] = {
- "wmiir - window manager improved remote - " VERSION "\n"
- " (C)opyright MMIV-MMVI Anselm R. Garbe\n", 0
-};
-
-static void
-usage()
-{
- fprintf(stderr, "%s",
- "usage: wmiir [-a <server address>] [-v] <command>\n"
- " -a server address (default: $WMIIR_ADDRESS)\n"
- " -v version info\n"
- "valid commands:\n"
- " create <file> -- creates file and writes data from stdin to file\n"
- " read <file/dir> -- prints file/directory contents\n"
- " write <file> -- writes data from stdin to file\n"
- " remove <file> -- removes file\n");
- exit(1);
-}
-
-static void
-write_data(unsigned int fid)
-{
- void *data = cext_emallocz(c.fcall.iounit);
- unsigned long long offset = 0;
- size_t len = 0;
-
- while((len = read(0, data, c.fcall.iounit)) > 0) {
- fprintf(stderr, "read=%d, bufsz=%d\n", len, c.fcall.iounit);
- if(ixp_client_write
- (&c, fid, offset, len, data) != len) {
- fprintf(stderr, "wmiir: cannot write file: %s\n", c.errstr);
- break;
- }
- offset += len;
- }
- free(data);
-}
-
-static int
-xcreate(char *file)
-{
- unsigned int fid;
- char *p = strrchr(file, '/');
-
- fid = c.root_fid << 2;
- /* walk to bottom-most directory */
- *p = 0;
- if(ixp_client_walk(&c, fid, file) == -1) {
- fprintf(stderr, "wmiir: cannot walk to '%s': %s\n", file, c.errstr);
- return -1;
- }
- /* create */
- p++;
- if(ixp_client_create(&c, fid, p, (unsigned int) 0xff, IXP_OWRITE) == -1) {
- fprintf(stderr, "wmiir: cannot create file '%s': %s\n", p, c.errstr);
- return -1;
- }
- write_data(fid);
- return ixp_client_close(&c, fid);
-}
-
-static int
-xwrite(char *file)
-{
-
- /* open */
- unsigned int fid = c.root_fid << 2;
- if(ixp_client_open(&c, fid, file, IXP_OWRITE) == -1) {
- fprintf(stderr, "wmiir: cannot open file '%s': %s\n", file, c.errstr);
- return -1;
- }
- write_data(fid);
- return ixp_client_close(&c, fid);
-}
-
-static int
-comp(const void *s1, const void *s2)
-{
- return strcmp(*(char **)s1, *(char **)s2);
-}
-
-static void
-xls(void *result, unsigned int msize)
-{
- size_t n = 0, j = 0;
- char buf[IXP_MAX_FLEN];
- void *p = result;
- char **dir;
- static Stat stat, zerostat = { 0 };
- do {
- p = ixp_dec_stat(p, &stat);
- n++;
- }
- while(p - result < msize);
- dir = (char **)cext_emallocz(sizeof(char *) * n);
- p = result;
- do {
- p = ixp_dec_stat(p, &stat);
- if(stat.qid.type == IXP_QTDIR)
- snprintf(buf, sizeof(buf), "%s/", stat.name);
- else
- snprintf(buf, sizeof(buf), "%s", stat.name);
- dir[j++] = cext_estrdup(buf);
- stat = zerostat;
- }
- while(p - result < msize);
- qsort(dir, n, sizeof(char *), comp);
- for(j = 0; j < n; j++) {
- fprintf(stdout, "%s\n", dir[j]);
- free(dir[j]);
- }
- free(dir);
-}
-
-static int
-xread(char *file)
-{
- unsigned int fid = c.root_fid << 2;
- int count, is_directory = 0;
- static unsigned char result[IXP_MAX_MSG];
- unsigned long long offset = 0;
-
- /* open */
- if(ixp_client_open(&c, fid, file, IXP_OREAD) == -1) {
- fprintf(stderr, "wmiir: cannot open file '%s': %s\n", file, c.errstr);
- return -1;
- }
- is_directory = !c.fcall.nwqid || (c.fcall.qid.type == IXP_QTDIR);
-
- /* read */
- while((count = ixp_client_read(&c, fid, offset, result, IXP_MAX_MSG)) > 0) {
- if(is_directory)
- xls(result, count);
- else {
- unsigned int i;
- for(i = 0; i < count; i++)
- fputc(result[i], stdout);
- fflush(stdout);
- }
- offset += count;
- }
- if(count == -1) {
- fprintf(stderr, "wmiir: cannot read file/directory '%s': %s\n", file, c.errstr);
- return -1;
- }
- return ixp_client_close(&c, fid);
-}
-
-static int
-xremove(char *file)
-{
- unsigned int fid;
-
- /* remove */
- fid = c.root_fid << 2;
- if(ixp_client_remove(&c, fid, file) == -1) {
- fprintf(stderr, "wmiir: cannot remove file '%s': %s\n", file, c.errstr);
- return -1;
- }
- return 0;
-}
-
-int
-main(int argc, char *argv[])
-{
- int i = 0;
- char *cmd, *file, *sockfile = getenv("WMIIR_ADDRESS");
-
- /* command line args */
- if(argc < 2)
- usage();
-
- for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) {
- switch (argv[i][1]) {
- case 'v':
- fprintf(stderr, "%s", version[0]);
- exit(0);
- break;
- case 'a':
- if(i + 1 < argc)
- sockfile = argv[++i];
- else
- usage();
- break;
- default:
- usage();
- break;
- }
- }
- cmd = argv[argc - 2];
- file = argv[argc - 1];
-
- if(!sockfile) {
- fprintf(stderr, "%s", "wmiir: error: $WMIIR_ADDRESS not set\n");
- usage();
- }
- /* open socket */
- if(ixp_client_init(&c, sockfile) == -1) {
- fprintf(stderr, "wmiir: %s\n", c.errstr);
- exit(1);
- }
-
- if(!strncmp(cmd, "create", 7))
- xcreate(file);
- else if(!strncmp(cmd, "write", 6))
- xwrite(file);
- else if(!strncmp(cmd, "read", 5))
- xread(file);
- else if(!strncmp(cmd, "remove", 7))
- xremove(file);
- else
- usage();
-
- /* close socket */
- ixp_client_deinit(&c);
-
- return 0;
-}
diff --git a/libixp/Makefile b/libixp/Makefile
@@ -4,14 +4,13 @@
include ../config.mk
CFLAGS += -I ../libcext
-LDFLAGS += -L../libcext -lcext
-SRC = client.c message.c ramfs.c server.c
+SRC = client.c convert.c message.c server.c socket.c transport.c
OBJ = ${SRC:.c=.o}
all: libixp
- @echo built libixp
+ @echo built libixp2
.c.o:
@echo CC $<
diff --git a/libixp/client.c b/libixp/client.c
@@ -3,288 +3,192 @@
* See LICENSE file for license details.
*/
-#include <errno.h>
-#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/stat.h>
#include <sys/socket.h>
-#include <sys/un.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include "cext.h"
#include "ixp.h"
-#include <cext.h>
+static unsigned char msg[IXP_MAX_MSG];
-static size_t offsets[MAX_CONN * MAX_OPEN_FILES][2]; /* set of possible fd's */
-
-static void check_error(IXPClient * c, void *msg)
-{
- ResHeader h;
-
- if (c->errstr)
- free(c->errstr);
- c->errstr = 0;
-
- memcpy(&h, msg, sizeof(ResHeader));
- if (h.res == RERROR)
- c->errstr = strdup((char *) msg + sizeof(ResHeader));
-}
-
-static void handle_dead_server(IXPClient * c)
-{
- if (c->errstr)
- free(c->errstr);
- c->errstr = strdup(DEAD_SERVER);
- if (c->fd) {
- shutdown(c->fd, SHUT_RDWR);
- close(c->fd);
- }
- c->fd = -1;
-}
-
-static void *poll_server(IXPClient * c, void *request, size_t req_len,
- size_t * out_len)
-{
- size_t num = 0;
- void *result = 0;
- int r, header = 0;
-
- if (c->errstr)
- free(c->errstr);
- c->errstr = 0;
-
- /* first send request */
- while (num < req_len) {
- FD_ZERO(&c->wr);
- FD_SET(c->fd, &c->wr);
- r = select(c->fd + 1, 0, &c->wr, 0, 0);
- if (r == -1 && errno == EINTR)
- continue;
- if (r < 0) {
- perror("ixp: client: select");
- if (result)
- free(result);
- handle_dead_server(c);
- return 0;
- } else if (r > 0) {
- if (!header) {
- /* write header first */
- r = write(c->fd, &req_len, sizeof(size_t));
- if (r != sizeof(size_t)) {
- if (result)
- free(result);
- handle_dead_server(c);
- return 0;
- }
- header = 1;
- }
- r = write(c->fd, ((char *) request) + num, req_len - num);
- if (r < 1) {
- perror("ixp: client: write");
- if (result)
- free(result);
- handle_dead_server(c);
- return 0;
- }
- num += r;
- }
- }
- free(request); /* cleanup */
-
- num = 0;
- header = 0;
- /* now wait for response */
- do {
- FD_ZERO(&c->rd);
- FD_SET(c->fd, &c->rd);
- r = select(c->fd + 1, &c->rd, 0, 0, 0);
- if (r == -1 && errno == EINTR)
- continue;
- if (r < 0) {
- perror("ixp: client: select");
- if (result)
- free(result);
- handle_dead_server(c);
- return 0;
- } else if (r > 0) {
- if (!header) {
- r = read(c->fd, out_len, sizeof(size_t));
- if (r != sizeof(size_t)) {
- if (result)
- free(result);
- handle_dead_server(c);
- return 0;
- }
- result = cext_emallocz(*out_len);
- header = 1;
- }
- r = read(c->fd, ((char *) result) + num, *out_len - num);
- if (r < 1) {
- perror("ixp: client: read");
- if (result)
- free(result);
- handle_dead_server(c);
- return 0;
- }
- num += r;
- }
- }
- while (num != *out_len);
-
- /* error checking */
- if (result)
- check_error(c, result);
- if (c->errstr) {
- free(result);
- result = 0;
- }
- return result;
-}
-
-static void cixp_create(IXPClient * c, char *path)
+static int
+do_fcall(IXPClient * c)
{
- ResHeader h;
- size_t req_len, res_len;
- void *req = tcreate_message(path, &req_len);
- void *result = poll_server(c, req, req_len, &res_len);
-
- if (!result)
- return;
- memcpy(&h, result, sizeof(ResHeader));
- free(result);
+ unsigned int msize = ixp_fcall_to_msg(&c->fcall, msg, IXP_MAX_MSG);
+ c->errstr = 0;
+ if(ixp_send_message(c->fd, msg, msize, &c->errstr) != msize)
+ return -1;
+ if(!ixp_recv_message(c->fd, msg, IXP_MAX_MSG, &c->errstr))
+ return -1;
+ if(!(msize = ixp_msg_to_fcall(msg, IXP_MAX_MSG, &c->fcall))) {
+ c->errstr = "received bad message";
+ return -1;
+ }
+ if(c->fcall.id == RERROR) {
+ c->errstr = c->fcall.errstr;
+ return -1;
+ }
+ return 0;
}
-static int cixp_open(IXPClient * c, char *path)
+int
+ixp_client_init(IXPClient * c, char *sockfile)
{
- ResHeader h;
- size_t req_len, res_len;
- void *req = topen_message(path, &req_len);
- void *result = poll_server(c, req, req_len, &res_len);
-
- if (!result)
- return -1;
- memcpy(&h, result, sizeof(ResHeader));
- free(result);
- offsets[h.fd][0] = offsets[h.fd][1] = 0;
- return h.fd;
+ if((c->fd = ixp_connect_sock(sockfile)) < 0) {
+ c->errstr = "cannot connect server";
+ return -1;
+ }
+ /* version */
+ c->fcall.id = TVERSION;
+ c->fcall.tag = IXP_NOTAG;
+ c->fcall.maxmsg = IXP_MAX_MSG;
+ cext_strlcpy(c->fcall.version, IXP_VERSION, sizeof(c->fcall.version));
+ if(do_fcall(c) == -1) {
+ ixp_client_deinit(c);
+ return -1;
+ }
+ if(strncmp(c->fcall.version, IXP_VERSION, strlen(IXP_VERSION))) {
+ c->errstr = "9P versions differ";
+ ixp_client_deinit(c);
+ return -1; /* we cannot handle this version */
+ }
+ c->root_fid = getpid();
+
+ /* attach */
+ c->fcall.id = TATTACH;
+ c->fcall.tag = IXP_NOTAG;
+ c->fcall.fid = c->root_fid;
+ c->fcall.afid = IXP_NOFID;
+ cext_strlcpy(c->fcall.uname, getenv("USER"), sizeof(c->fcall.uname));
+ c->fcall.aname[0] = 0;
+ if(do_fcall(c) == -1) {
+ ixp_client_deinit(c);
+ return -1;
+ }
+ c->root_qid = c->fcall.qid;
+ return 0;
}
-static size_t
-cixp_read(IXPClient * c, int fd, void *out_buf, size_t out_buf_len)
+int
+ixp_client_remove(IXPClient * c, unsigned int newfid, char *filepath)
{
- size_t len;
-
- len = seek_read(c, fd, offsets[fd][0], out_buf, out_buf_len);
- if (c->errstr)
- return 0;
- if (len == out_buf_len)
- offsets[fd][0] += len;
- return len;
+ if(ixp_client_walk(c, newfid, filepath) == -1)
+ return -1;
+ /* remove */
+ c->fcall.id = TREMOVE;
+ c->fcall.tag = IXP_NOTAG;
+ c->fcall.fid = newfid;
+ return do_fcall(c);
}
-size_t
-seek_read(IXPClient * c, int fd, size_t offset,
- void *out_buf, size_t out_buf_len)
+int
+ixp_client_create(IXPClient * c, unsigned int dirfid, char *name,
+ unsigned int perm, unsigned char mode)
{
- ResHeader h;
- size_t req_len, res_len;
- void *req = tread_message(fd, offset, out_buf_len, &req_len);
- void *result = poll_server(c, req, req_len, &res_len);
-
- if (!result)
- return -1;
- memcpy(&h, result, sizeof(ResHeader));
- memcpy(out_buf, ((char *) result) + sizeof(ResHeader), h.buf_len);
- free(result);
- return h.buf_len;
+ /* create */
+ c->fcall.id = TCREATE;
+ c->fcall.tag = IXP_NOTAG;
+ c->fcall.fid = dirfid;
+ cext_strlcpy(c->fcall.name, name, sizeof(c->fcall.name));
+ c->fcall.perm = perm;
+ c->fcall.mode = mode;
+ return do_fcall(c);
}
-static void cixp_write(IXPClient * c, int fd, void *content, size_t in_len)
+int
+ixp_client_walk(IXPClient * c, unsigned int newfid, char *filepath)
{
- seek_write(c, fd, offsets[fd][1], content, in_len);
- if (!c->errstr)
- offsets[fd][1] += in_len;
+ unsigned int i;
+ char *wname[IXP_MAX_WELEM];
+ /* walk */
+ c->fcall.id = TWALK;
+ c->fcall.fid = c->root_fid;
+ c->fcall.newfid = newfid;
+ if(filepath) {
+ cext_strlcpy(c->fcall.name, filepath, sizeof(c->fcall.name));
+ c->fcall.nwname =
+ cext_tokenize(wname, IXP_MAX_WELEM, c->fcall.name, '/');
+ for(i = 0; i < c->fcall.nwname; i++)
+ cext_strlcpy(c->fcall.wname[i], wname[i], sizeof(c->fcall.wname[i]));
+ }
+ return do_fcall(c);
}
-void
-seek_write(IXPClient * c, int fd, size_t offset, void *content,
- size_t in_len)
+int
+ixp_client_open(IXPClient * c, unsigned int newfid, char *filepath,
+ unsigned char mode)
{
- ResHeader h;
- size_t req_len, res_len;
- void *req = twrite_message(fd, offset, content, in_len, &req_len);
- void *result = poll_server(c, req, req_len, &res_len);
-
- if (!result)
- return;
- memcpy(&h, result, sizeof(ResHeader));
- free(result);
+ if(ixp_client_walk(c, newfid, filepath) == -1)
+ return -1;
+
+ /* open */
+ c->fcall.id = TOPEN;
+ c->fcall.tag = IXP_NOTAG;
+ c->fcall.fid = newfid;
+ c->fcall.mode = mode;
+ return do_fcall(c);
}
-static void cixp_close(IXPClient * c, int fd)
+int
+ixp_client_read(IXPClient * c, unsigned int fid, unsigned long long offset,
+ void *result, unsigned int res_len)
{
- ResHeader h;
- size_t req_len, res_len;
- void *req = tclose_message(fd, &req_len);
- void *result = poll_server(c, req, req_len, &res_len);
-
- if (!result)
- return;
- memcpy(&h, result, sizeof(ResHeader));
- free(result);
- offsets[fd][0] = offsets[fd][1] = 0;
+ unsigned int bytes = c->fcall.iounit;
+
+ /* read */
+ c->fcall.id = TREAD;
+ c->fcall.tag = IXP_NOTAG;
+ c->fcall.fid = fid;
+ c->fcall.offset = offset;
+ c->fcall.count = res_len < bytes ? res_len : bytes;
+ if(do_fcall(c) == -1)
+ return -1;
+ memcpy(result, c->fcall.data, c->fcall.count);
+ return c->fcall.count;
}
-static void cixp_remove(IXPClient * c, char *path)
+int
+ixp_client_write(IXPClient * c, unsigned int fid,
+ unsigned long long offset, unsigned int count,
+ unsigned char *data)
{
- ResHeader h;
- size_t req_len, res_len;
- void *req = tremove_message(path, &req_len);
- void *result = poll_server(c, req, req_len, &res_len);
-
- if (!result)
- return;
- memcpy(&h, result, sizeof(ResHeader));
- free(result);
+ if(count > c->fcall.iounit)
+ {
+ c->errstr = "iounit exceeded";
+ return -1;
+ }
+ /* write */
+ c->fcall.id = TWRITE;
+ c->fcall.tag = IXP_NOTAG;
+ c->fcall.fid = fid;
+ c->fcall.offset = offset;
+ c->fcall.count = count;
+ memcpy(c->fcall.data, data, count);
+ if(do_fcall(c) == -1)
+ return -1;
+ return c->fcall.count;
}
-IXPClient *init_ixp_client(char *sockfile)
+int
+ixp_client_close(IXPClient * c, unsigned int fid)
{
- struct sockaddr_un addr = { 0 };
- socklen_t su_len;
-
- /* init */
- IXPClient *c = (IXPClient *) cext_emallocz(sizeof(IXPClient));
- c->create = cixp_create;
- c->open = cixp_open;
- c->read = cixp_read;
- c->write = cixp_write;
- c->close = cixp_close;
- c->remove = cixp_remove;
-
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, sockfile, sizeof(addr.sun_path));
- su_len = sizeof(struct sockaddr) + strlen(addr.sun_path);
-
- if ((c->fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
- free(c);
- return 0;
- }
- if (connect(c->fd, (struct sockaddr *) &addr, su_len)) {
- close(c->fd);
- free(c);
- return 0;
- }
- return c;
+ /* clunk */
+ c->fcall.id = TCLUNK;
+ c->fcall.tag = IXP_NOTAG;
+ c->fcall.fid = fid;
+ return do_fcall(c);
}
-void deinit_client(IXPClient * c)
+void
+ixp_client_deinit(IXPClient * c)
{
- if (c->fd) {
- shutdown(c->fd, SHUT_RDWR);
- close(c->fd);
- }
- c->fd = -1;
- free(c);
+ /* session finished, now shutdown */
+ if(c->fd) {
+ shutdown(c->fd, SHUT_RDWR);
+ close(c->fd);
+ }
}
diff --git a/libixp/convert.c b/libixp/convert.c
@@ -0,0 +1,197 @@
+/*
+ * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
+ * See LICENSE file for license details.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ixp.h"
+
+/* encode/decode stuff */
+
+void *
+ixp_enc_u8(unsigned char *msg, unsigned char val)
+{
+ msg[0] = val;
+ return &msg[1];
+}
+
+void *
+ixp_dec_u8(unsigned char *msg, unsigned char *val)
+{
+ *val = msg[0];
+ return &msg[1];
+}
+
+void *
+ixp_enc_u16(unsigned char *msg, unsigned short val)
+{
+ msg[0] = val;
+ msg[1] = val >> 8;
+ return &msg[2];
+}
+
+void *
+ixp_dec_u16(unsigned char *msg, unsigned short *val)
+{
+ *val = msg[0] | (msg[1] << 8);
+ return &msg[2];
+}
+
+void *
+ixp_enc_u32(unsigned char *msg, unsigned int val)
+{
+ msg[0] = val;
+ msg[1] = val >> 8;
+ msg[2] = val >> 16;
+ msg[3] = val >> 24;
+ return &msg[4];
+}
+
+void *
+ixp_dec_u32(unsigned char *msg, unsigned int *val)
+{
+ *val = msg[0] | (msg[1] << 8) | (msg[2] << 16) | (msg[3] << 24);
+ return &msg[4];
+}
+
+void *
+ixp_enc_u64(unsigned char *msg, unsigned long long val)
+{
+ msg[0] = val;
+ msg[1] = val >> 8;
+ msg[2] = val >> 16;
+ msg[3] = val >> 24;
+ msg[4] = val >> 32;
+ msg[5] = val >> 40;
+ msg[6] = val >> 48;
+ msg[7] = val >> 56;
+ return &msg[8];
+}
+
+void *
+ixp_dec_u64(unsigned char *msg, unsigned long long *val)
+{
+ *val =
+ (unsigned long long) msg[0] | ((unsigned long long) msg[1] << 8) |
+ ((unsigned long long) msg[2] << 16) | ((unsigned long long) msg[3]
+ << 24) | ((unsigned long
+ long) msg[4] <<
+ 32) | ((unsigned
+ long long)
+ msg[5] <<
+ 40) |
+ ((unsigned long long) msg[6] << 48) | ((unsigned long long) msg[7]
+ << 56);
+ return &msg[8];
+}
+
+void *
+ixp_enc_string(unsigned char *msg, const char *s)
+{
+ unsigned short len = s ? strlen(s) : 0;
+ msg = ixp_enc_u16(msg, len);
+ if(s)
+ memcpy(msg, s, len);
+ return &msg[len];
+}
+
+void *
+ixp_dec_string(unsigned char *msg, char *string, unsigned short stringlen,
+ unsigned short *len)
+{
+ msg = ixp_dec_u16(msg, len);
+ if(!(*len))
+ return msg;
+ if(*len > stringlen - 1)
+ /* might never happen if stringlen == IXP_MAX_MSG */
+ string[0] = 0;
+ else {
+ memcpy(string, msg, *len);
+ string[*len] = 0;
+ }
+ return &msg[*len];
+}
+
+void *
+ixp_enc_data(unsigned char *msg, unsigned char *data, unsigned int datalen)
+{
+ memcpy(msg, data, datalen);
+ return &msg[datalen];
+}
+
+void *
+ixp_dec_data(unsigned char *msg, unsigned char *data, unsigned int datalen)
+{
+ memcpy(data, msg, datalen);
+ return &msg[datalen];
+}
+
+void *
+ixp_enc_prefix(unsigned char *msg, unsigned int size, unsigned char id,
+ unsigned short tag)
+{
+ msg = ixp_enc_u32(msg, size);
+ msg = ixp_enc_u8(msg, id);
+ return ixp_enc_u16(msg, tag);
+}
+
+void *
+ixp_dec_prefix(unsigned char *msg, unsigned int *size, unsigned char *id,
+ unsigned short *tag)
+{
+ msg = ixp_dec_u32(msg, size);
+ msg = ixp_dec_u8(msg, id);
+ return ixp_dec_u16(msg, tag);
+}
+
+void *
+ixp_enc_qid(unsigned char *msg, Qid * qid)
+{
+ msg = ixp_enc_u8(msg, qid->type);
+ msg = ixp_enc_u32(msg, qid->version);
+ return ixp_enc_u64(msg, qid->path);
+}
+
+void *
+ixp_dec_qid(unsigned char *msg, Qid * qid)
+{
+ msg = ixp_dec_u8(msg, &qid->type);
+ msg = ixp_dec_u32(msg, &qid->version);
+ return ixp_dec_u64(msg, &qid->path);
+}
+
+void *
+ixp_enc_stat(unsigned char *msg, Stat * stat)
+{
+ msg = ixp_enc_u16(msg, ixp_sizeof_stat(stat) - sizeof(unsigned short));
+ msg = ixp_enc_u16(msg, stat->type);
+ msg = ixp_enc_u32(msg, stat->dev);
+ msg = ixp_enc_qid(msg, &stat->qid);
+ msg = ixp_enc_u32(msg, stat->mode);
+ msg = ixp_enc_u32(msg, stat->atime);
+ msg = ixp_enc_u32(msg, stat->mtime);
+ msg = ixp_enc_u64(msg, stat->length);
+ msg = ixp_enc_string(msg, stat->name);
+ msg = ixp_enc_string(msg, stat->uid);
+ msg = ixp_enc_string(msg, stat->gid);
+ return ixp_enc_string(msg, stat->muid);
+}
+
+void *
+ixp_dec_stat(unsigned char *msg, Stat * stat)
+{
+ unsigned short dummy;
+ msg += sizeof(unsigned short);
+ msg = ixp_dec_u16(msg, &stat->type);
+ msg = ixp_dec_u32(msg, &stat->dev);
+ msg = ixp_dec_qid(msg, &stat->qid);
+ msg = ixp_dec_u32(msg, &stat->mode);
+ msg = ixp_dec_u32(msg, &stat->atime);
+ msg = ixp_dec_u32(msg, &stat->mtime);
+ msg = ixp_dec_u64(msg, &stat->length);
+ msg = ixp_dec_string(msg, stat->name, sizeof(stat->name), &dummy);
+ msg = ixp_dec_string(msg, stat->uid, sizeof(stat->uid), &dummy);
+ msg = ixp_dec_string(msg, stat->gid, sizeof(stat->gid), &dummy);
+ return ixp_dec_string(msg, stat->muid, sizeof(stat->muid), &dummy);
+}
diff --git a/libixp/ixp.h b/libixp/ixp.h
@@ -1,172 +1,289 @@
/*
- * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
+ *(C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
+ *See LICENSE file for license details.
*/
#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-#define MAX_CONN 32
-#define MAX_OPEN_FILES 16
-#define DEAD_SERVER "server closed connection unexpectedly"
-#define MAX_SEEN_SHUTDOWN 3
+#ifndef nil
+#define nil 0
+#endif
-#define xMAX(x,y) ((x) > (y) ? (x) : (y))
+#define IXP_VERSION "9P2000"
+#define IXP_MAX_VERSION 32
+#define IXP_MAX_ERROR 128
+#define IXP_MAX_CACHE 32
+#define IXP_MAX_MSG 8192
+#define IXP_MAX_FLEN 128
+#define IXP_MAX_ULEN 32
+#define IXP_MAX_STAT 64
+#define IXP_MAX_WELEM 16 /*MAXWELEM */
+#define IXP_MAX_TFUNCS 14
-/* 9P message types */
+
+/*
+ size[4] Tversion tag[2] msize[4] version[s]
+ size[4] Rversion tag[2] msize[4] version[s]
+ size[4] Tauth tag[2] afid[4] uname[s] aname[s]
+ size[4] Rauth tag[2] aqid[13]
+ size[4] Rerror tag[2] ename[s]
+ size[4] Tflush tag[2] oldtag[2]
+ size[4] Rflush tag[2]
+ size[4] Tattach tag[2] fid[4] afid[4] uname[s] aname[s]
+ size[4] Rattach tag[2] qid[13]
+ size[4] Twalk tag[2] fid[4] newfid[4] nwname[2] nwname*(wname[s])
+ size[4] Rwalk tag[2] nwqid[2] nwqid*(wqid[13])
+ size[4] Topen tag[2] fid[4] mode[1]
+ size[4] Ropen tag[2] qid[13] iounit[4]
+ size[4] Tcreate tag[2] fid[4] name[s] perm[4] mode[1]
+ size[4] Rcreate tag[2] qid[13] iounit[4]
+ size[4] Tread tag[2] fid[4] offset[8] count[4]
+ size[4] Rread tag[2] count[4] data[count]
+ size[4] Twrite tag[2] fid[4] offset[8] count[4] data[count]
+ size[4] Rwrite tag[2] count[4]
+ size[4] Tclunk tag[2] fid[4]
+ size[4] Rclunk tag[2]
+ size[4] Tremove tag[2] fid[4]
+ size[4] Rremove tag[2]
+ size[4] Tstat tag[2] fid[4]
+ size[4] Rstat tag[2] stat[n]
+ size[4] Twstat tag[2] fid[4] stat[n]
+ size[4] Rwstat tag[2]
+
+ stat[n]:
+ size[2] total byte count of the following data
+ type[2] for kernel use
+ dev[4] for kernel use
+ qid.type[1] the type of the file (directory, etc.),
+ represented as a bit vector corresponding to the high 8 bits of the file's mode word.
+ qid.vers[4] version number for given path
+ qid.path[8] the file server's unique identification for the file
+ mode[4] permissions and flags
+ atime[4] last access time
+ mtime[4] last modification time
+ length[8] length of file in bytes
+ name[ s ] file name; must be / if the file is the root directory of the server
+ uid[ s ] owner name
+ gid[ s ] group name
+ muid[ s ]
+*/
+
+/*9P message types */
enum {
- TVERSION = 100,
- RVERSION,
- TAUTH = 102,
- RAUTH,
- TATTACH = 104,
- RATTACH,
- TERROR = 106,
- RERROR,
- TFLUSH = 108,
- RFLUSH,
- TWALK = 110,
- RWALK,
- TOPEN = 112,
- ROPEN,
- TCREATE = 114,
- RCREATE,
- TREAD = 116,
- RREAD,
- TWRITE = 118,
- RWRITE,
- TCLUNK = 120,
- RCLUNK,
- TREMOVE = 122,
- RREMOVE,
- TSTAT = 124,
- RSTAT,
- TWSTAT = 126,
- RWSTAT,
+ TVERSION = 100,
+ RVERSION,
+ TAUTH = 102,
+ RAUTH,
+ TATTACH = 104,
+ RATTACH,
+ TERROR = 106,
+ RERROR,
+ TFLUSH = 108,
+ RFLUSH,
+ TWALK = 110,
+ RWALK,
+ TOPEN = 112,
+ ROPEN,
+ TCREATE = 114,
+ RCREATE,
+ TREAD = 116,
+ RREAD,
+ TWRITE = 118,
+ RWRITE,
+ TCLUNK = 120,
+ RCLUNK,
+ TREMOVE = 122,
+ RREMOVE,
+ TSTAT = 124,
+ RSTAT,
+ TWSTAT = 126,
+ RWSTAT,
};
-typedef struct ResHeader ResHeader;
-typedef struct ReqHeader ReqHeader;
-typedef struct Connection Connection;
-typedef struct File File;
-typedef struct IXPClient IXPClient;
-typedef struct IXPServer IXPServer;
-typedef int IXPRequest;
-typedef int IXPResponse;
-typedef enum {
- HALT, SHUTDOWN, RUNNING
-} IXPRunlevel;
-
-struct ReqHeader {
- IXPRequest req;
- int fd;
- size_t offset;
- size_t buf_len;
-};
+/*borrowed from libc.h of Plan 9 */
+#define DMDIR 0x80000000 /*mode bit for directories */
+#define DMAPPEND 0x40000000 /*mode bit for append only files */
+#define DMEXCL 0x20000000 /*mode bit for exclusive use files */
+#define DMMOUNT 0x10000000 /*mode bit for mounted channel */
+#define DMAUTH 0x08000000 /*mode bit for authentication file */
+#define DMTMP 0x04000000 /*mode bit for non-backed-up file */
+
+#define DMREAD 0x4<<6 /*mode bit for read permission */
+#define DMWRITE 0x2<<6 /*mode bit for write permission */
+#define DMEXEC 0x1<<6 /*mode bit for execute permission */
-struct ResHeader {
- IXPResponse res;
- int fd;
- size_t buf_len;
+/*modes */
+enum {
+ IXP_OREAD = 0x00,
+ IXP_OWRITE = 0x01,
+ IXP_ORDWR = 0x02,
+ IXP_OEXEC = 0x03,
+ IXP_OEXCL = 0x04,
+ IXP_OTRUNC = 0x10,
+ IXP_OREXEC = 0x20,
+ IXP_ORCLOSE = 0x40,
+ IXP_OAPPEND = 0x80,
};
-/** Definition of a connection to IXP */
-struct Connection {
- IXPServer *s; /* !< server for this connection */
- int index; /* !< index inside server */
- int fd; /* !< file descriptor */
- int mode; /* 0 for reading, 1 for writing */
- int header;
- void *data;
- size_t len;
- size_t remain;
- void (*read) (Connection *);
- void (*write) (Connection *);
- File *files[MAX_OPEN_FILES];
- int seen[MAX_OPEN_FILES];
+/*qid.types */
+enum {
+ IXP_QTDIR = 0x80,
+ IXP_QTAPPEND = 0x40,
+ IXP_QTEXCL = 0x20,
+ IXP_QTMOUNT = 0x10,
+ IXP_QTAUTH = 0x08,
+ IXP_QTTMP = 0x04,
+ IXP_QTSYMLINK = 0x02,
+ IXP_QTLINK = 0x01,
+ IXP_QTFILE = 0x00,
};
-struct File {
- char *name;
- void *content;
- size_t size;
- int bind;
- File *parent;
- File *next;
- /* introduced IXPServer in signature for IXPServer->errstr */
- void (*after_write) (IXPServer * s, File *);
- void (*before_read) (IXPServer * s, File *);
+#define IXP_NOTAG (unsigned short)~0U /*Dummy tag */
+#define IXP_NOFID (unsigned int)~0 /*No auth */
+
+typedef struct {
+ unsigned char type;
+ unsigned int version;
+ unsigned long long path;
+} Qid;
+
+/*stat structure */
+typedef struct {
+ unsigned short type;
+ unsigned int dev;
+ Qid qid;
+ unsigned int mode;
+ unsigned int atime;
+ unsigned int mtime;
+ unsigned long long length;
+ char name[IXP_MAX_FLEN];
+ char uid[IXP_MAX_ULEN];
+ char gid[IXP_MAX_ULEN];
+ char muid[IXP_MAX_ULEN];
+} Stat;
+
+typedef struct {
+ unsigned char id;
+ unsigned short tag;
+ unsigned int fid;
+ unsigned int maxmsg; /*Tversion, Rversion */
+ char version[IXP_MAX_VERSION]; /*Tversion, Rversion */
+ unsigned short oldtag; /*Tflush */
+ char errstr[IXP_MAX_ERROR]; /*Rerror */
+ Qid qid; /*Rattach, Ropen, Rcreate */
+ unsigned int iounit; /*Ropen, Rcreate */
+ Qid aqid; /*Rauth */
+ unsigned int afid; /*Tauth, Tattach */
+ char uname[IXP_MAX_ULEN]; /*Tauth, Tattach */
+ char aname[IXP_MAX_FLEN]; /*Tauth, Tattach */
+ unsigned int perm; /*Tcreate */
+ char name[IXP_MAX_FLEN]; /*Tcreate */
+ unsigned char mode; /*Tcreate, Topen */
+ unsigned int newfid; /*Twalk */
+ unsigned short nwname; /*Twalk */
+ char wname[IXP_MAX_WELEM][IXP_MAX_FLEN]; /*Twalk */
+ unsigned short nwqid; /*Rwalk */
+ Qid wqid[IXP_MAX_WELEM]; /*Rwalk */
+ unsigned long long offset; /*Tread, Twrite */
+ unsigned int count; /*Tread, Twrite, Rread */
+ Stat stat; /*Rstat */
+ unsigned short nstat; /*Twstat, Rstat */
+ unsigned char data[IXP_MAX_MSG]; /*Twrite, Rread, Twstat,
+ *Rstat */
+} Fcall;
+
+typedef struct IXPServer IXPServer;
+typedef struct IXPConn IXPConn;
+typedef struct IXPMap IXPMap;
+
+struct IXPMap {
+ unsigned int fid;
+ Qid qid;
};
-struct IXPClient {
- int fd;
- fd_set rd, wr;
- char *errstr; /* 0 if succes, CHECK AFTER EACH of following
- * operations */
- /* returns fd if path exists */
- void (*create) (IXPClient *, char *path);
- void (*remove) (IXPClient *, char *path);
- int (*open) (IXPClient *, char *path);
- void (*close) (IXPClient *, int fd);
- size_t(*read) (IXPClient *, int fd, void *out_buf, size_t out_buf_len);
- void (*write) (IXPClient *, int fd, void *content, size_t in_len);
+struct IXPConn {
+ int fd;
+ void (*read) (IXPServer *, IXPConn *);
+ void (*close) (IXPServer *, IXPConn *);
+ IXPMap **map;
+ size_t mapsz;
+ Fcall *fcall;
+ Fcall **pend;
+ size_t pendsz;
};
struct IXPServer {
- char *sockfile;
- IXPRunlevel runlevel;
- Connection conn[MAX_CONN];
- fd_set rd, wr; /* socks to wakeup while select() */
- int nfds; /* number of file descriptors */
- File *root;
- char *errstr; /* 0 if succes, CHECK AFTER EACH of following
- * operations */
- File *(*create) (IXPServer *, char *);
- File *(*open) (IXPServer *, char *);
- size_t(*read) (IXPServer *, int, size_t, void *, size_t);
- void (*write) (IXPServer *, int, size_t, void *, size_t);
- void (*close) (IXPServer *, int);
- void (*remove) (IXPServer *, char *);
+ int running;
+ IXPConn **conn;
+ size_t connsz;
+ int maxfd;
+ fd_set rd;
};
-/* client.c, implements client stub functions for fs access */
-IXPClient *init_ixp_client(char *sockfile);
-void deinit_client(IXPClient * c);
-size_t seek_read(IXPClient * c, int fd, size_t offset, void *out_buf, size_t out_buf_len);
-void seek_write(IXPClient * c, int fd, size_t offset, void *content, size_t in_len);
+typedef struct {
+ int fd;
+ unsigned int root_fid;
+ Qid root_qid;
+ Fcall fcall;
+ char *errstr;
+} IXPClient;
+
+/* client.c */
+int ixp_client_init(IXPClient *c, char *address);
+void ixp_client_deinit(IXPClient *c);
+int ixp_client_remove(IXPClient *c, unsigned int newfid, char *filepath);
+int ixp_client_create(IXPClient *c, unsigned int dirfid, char *name,
+ unsigned int perm, unsigned char mode);
+int ixp_client_walk(IXPClient *c, unsigned int newfid, char *filepath);
+int ixp_client_open(IXPClient *c, unsigned int newfid, char *filepath,
+ unsigned char mode);
+int ixp_client_read(IXPClient *c, unsigned int fid,
+ unsigned long long offset, void *result,
+ unsigned int res_len);
+int ixp_client_write(IXPClient *c, unsigned int fid,
+ unsigned long long offset,
+ unsigned int count, unsigned char *data);
+int ixp_client_close(IXPClient *c, unsigned int fid);
+
+/* convert.c */
+void *ixp_enc_u8(unsigned char *msg, unsigned char val);
+void *ixp_dec_u8(unsigned char *msg, unsigned char *val);
+void *ixp_enc_u16(unsigned char *msg, unsigned short val);
+void *ixp_dec_u16(unsigned char *msg, unsigned short *val);
+void *ixp_enc_u32(unsigned char *msg, unsigned int val);
+void *ixp_dec_u32(unsigned char *msg, unsigned int *val);
+void *ixp_enc_u64(unsigned char *msg, unsigned long long val);
+void *ixp_dec_u64(unsigned char *msg, unsigned long long *val);
+void *ixp_enc_string(unsigned char *msg, const char *s);
+void *ixp_dec_string(unsigned char *msg, char *string,
+ unsigned short stringlen, unsigned short *len);
+void *ixp_enc_data(unsigned char *msg, unsigned char *data,
+ unsigned int datalen);
+void *ixp_dec_data(unsigned char *msg, unsigned char *data,
+ unsigned int datalen);
+void *ixp_enc_prefix(unsigned char *msg, unsigned int size,
+ unsigned char id, unsigned short tag);
+void *ixp_dec_prefix(unsigned char *msg, unsigned int *size,
+ unsigned char *id, unsigned short *tag);
+void *ixp_enc_qid(unsigned char *msg, Qid *qid);
+void *ixp_dec_qid(unsigned char *msg, Qid *qid);
+void *ixp_enc_stat(unsigned char *msg, Stat *stat);
+void *ixp_dec_stat(unsigned char *msg, Stat *stat);
/* message.c */
-void *tcreate_message(char *path, size_t * msg_len);
-void *topen_message(char *path, size_t * msg_len);
-void *tread_message(int fd, size_t offset, size_t buf_len, size_t * msg_len);
-void *twrite_message(int fd, size_t offset, void *msg, size_t in_len, size_t * msg_len);
-void *tclose_message(int fd, size_t * msg_len);
-void *tremove_message(char *path, size_t * msg_len);
-void *rcreate_message(size_t * msg_len);
-void *ropen_message(int fd, size_t * msg_len);
-void *rread_message(void *content, size_t content_len, size_t * msg_len);
-void *rwrite_message(size_t * msg_len);
-void *rclose_message(size_t * msg_len);
-void *rremove_message(size_t * msg_len);
-void *rerror_message(char *errstr, size_t * msg_len);
-
-/* ramfs.c */
-int is_directory(File * f);
-File *ixp_walk(IXPServer * s, char *path);
-File *ixp_create(IXPServer * s, char *path);
-File *ixp_open(IXPServer * s, char *path);
-size_t ixp_read(IXPServer * s, int fd, size_t offset, void *out_buf, size_t out_buf_len);
-void ixp_write(IXPServer * s, int fd, size_t offset, void *content, size_t in_len);
-void ixp_close(IXPServer * s, int fd);
-void ixp_remove(IXPServer * s, char *path);
-void ixp_remove_file(IXPServer * s, File * f);
-
-/* server.c, uses fs directly for manipulation */
-IXPServer *init_server(char *sockfile, void (*cleanup) (void));
-void deinit_server(IXPServer * s);
-File *fd_to_file(IXPServer * s, int fd);
-void run_server(IXPServer * s);
-void run_server_with_fd_support(IXPServer * s, int fd, void (*fd_read) (Connection *), /* callback for read on fd */
- void (*fd_write) (Connection *)); /* callback for write on fd */
-void set_error(IXPServer * s, char *errstr);
+unsigned short ixp_sizeof_stat(Stat *stat);
+unsigned int ixp_fcall_to_msg(Fcall *fcall, void *msg, unsigned int msglen);
+unsigned int ixp_msg_to_fcall(void *msg, unsigned int msglen, Fcall *fcall);
+
+/* server.c */
+char *ixp_server_loop(IXPServer *s);
+IXPMap *ixp_server_fid2map(IXPConn *c, unsigned int fid);
+
+/* socket.c */
+int ixp_connect_sock(char *address);
+int ixp_accept_sock(int fd);
+int ixp_create_sock(char *address, char **errstr);
+
+/* transport.c */
+unsigned int ixp_send_message(int fd, void *msg, unsigned int msize, char **errstr);
+unsigned int ixp_recv_message(int fd, void *msg, unsigned int msglen, char **errstr);
diff --git a/libixp/message.c b/libixp/message.c
@@ -3,170 +3,315 @@
* See LICENSE file for license details.
*/
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-
#include "ixp.h"
-#include <cext.h>
+#define IXP_QIDSZ (sizeof(unsigned char) + sizeof(unsigned int)\
+ + sizeof(unsigned long long))
-void *tcreate_message(char *path, size_t * msg_len)
+static unsigned short
+sizeof_string(const char *s)
{
- char *msg;
- ReqHeader h;
- *msg_len = sizeof(ReqHeader) + strlen(path) + 1;
- msg = cext_emallocz(*msg_len);
- h.req = TCREATE;
- memcpy(msg, &h, sizeof(ReqHeader));
- memcpy(msg + sizeof(ReqHeader), path, strlen(path) + 1);
- return msg;
+ return sizeof(unsigned short) + strlen(s);
}
-void *topen_message(char *path, size_t * msg_len)
+unsigned short
+ixp_sizeof_stat(Stat * stat)
{
- char *msg;
- ReqHeader h;
- *msg_len = sizeof(ReqHeader) + strlen(path) + 1;
- msg = cext_emallocz(*msg_len);
- h.req = TOPEN;
- memcpy(msg, &h, sizeof(ReqHeader));
- memcpy(msg + sizeof(ReqHeader), path, strlen(path) + 1);
- return msg;
+ return IXP_QIDSZ
+ + 2 * sizeof(unsigned short)
+ + 4 * sizeof(unsigned int)
+ + sizeof(unsigned long long)
+ + sizeof_string(stat->name)
+ + sizeof_string(stat->uid)
+ + sizeof_string(stat->gid)
+ + sizeof_string(stat->muid);
}
-void *tread_message(int fd, size_t offset, size_t buf_len,
- size_t * msg_len)
+unsigned int
+ixp_fcall_to_msg(Fcall * fcall, void *msg, unsigned int msglen)
{
- char *msg;
- ReqHeader h;
- *msg_len = sizeof(ReqHeader);
- msg = cext_emallocz(*msg_len);
- h.req = TREAD;
- h.fd = fd;
- h.offset = offset;
- h.buf_len = buf_len;
- memcpy(msg, &h, sizeof(ReqHeader));
- return msg;
-}
-
-void *twrite_message(int fd, size_t offset, void *content,
- size_t content_len, size_t * msg_len)
-{
- char *msg;
- ReqHeader h;
- *msg_len = sizeof(ReqHeader) + content_len;
- msg = cext_emallocz(*msg_len);
- h.req = TWRITE;
- h.fd = fd;
- h.offset = offset;
- h.buf_len = content_len;
- memcpy(msg, &h, sizeof(ReqHeader));
- memcpy(msg + sizeof(ReqHeader), content, content_len);
- return msg;
-}
+ unsigned int i, msize =
+ sizeof(unsigned char) + sizeof(unsigned short) +
+ sizeof(unsigned int);
+ void *p = msg;
-void *tclose_message(int fd, size_t * msg_len)
-{
- char *msg;
- ReqHeader h;
- *msg_len = sizeof(ReqHeader);
- msg = cext_emallocz(*msg_len);
- h.req = TCLUNK;
- h.fd = fd;
- memcpy(msg, &h, sizeof(ReqHeader));
- return msg;
-}
+ switch (fcall->id) {
+ case TVERSION:
+ case RVERSION:
+ msize += sizeof(unsigned int) + sizeof_string(fcall->version);
+ break;
+ case TAUTH:
+ msize +=
+ sizeof(unsigned int) + sizeof_string(fcall->uname) +
+ sizeof_string(fcall->aname);
+ break;
+ case RAUTH:
+ case RATTACH:
+ msize += IXP_QIDSZ;
+ break;
+ case TATTACH:
+ msize +=
+ 2 * sizeof(unsigned int) + sizeof_string(fcall->uname) +
+ sizeof_string(fcall->aname);
+ break;
+ case RERROR:
+ msize += sizeof_string(fcall->errstr);
+ break;
+ case RWRITE:
+ case TCLUNK:
+ case TREMOVE:
+ case TSTAT:
+ msize += sizeof(unsigned int);
+ break;
+ case TWALK:
+ msize += sizeof(unsigned short) + 2 * sizeof(unsigned int);
+ for(i = 0; i < fcall->nwname; i++)
+ msize += sizeof_string(fcall->wname[i]);
+ break;
+ case TFLUSH:
+ msize += sizeof(unsigned short);
+ break;
+ case RWALK:
+ msize += sizeof(unsigned short) + fcall->nwqid * IXP_QIDSZ;
+ break;
+ case TOPEN:
+ msize += sizeof(unsigned int) + sizeof(unsigned char);
+ break;
+ case ROPEN:
+ case RCREATE:
+ msize += IXP_QIDSZ + sizeof(unsigned int);
+ break;
+ case TCREATE:
+ msize +=
+ sizeof(unsigned char) + 2 * sizeof(unsigned int) +
+ sizeof_string(fcall->name);
+ break;
+ case TREAD:
+ msize += 2 * sizeof(unsigned int) + sizeof(unsigned long long);
+ break;
+ case RREAD:
+ msize += sizeof(unsigned int) + fcall->count;
+ break;
+ case TWRITE:
+ msize +=
+ 2 * sizeof(unsigned int) + sizeof(unsigned long long) +
+ fcall->count;
+ break;
+ case RSTAT:
+ msize += sizeof(unsigned short) + ixp_sizeof_stat(&fcall->stat);
+ break;
+ case TWSTAT:
+ msize += sizeof(unsigned int) + sizeof(unsigned short) + ixp_sizeof_stat(&fcall->stat);
+ break;
+ default:
+ break;
+ }
-void *tremove_message(char *path, size_t * msg_len)
-{
- char *msg;
- ReqHeader h;
- *msg_len = sizeof(ReqHeader) + strlen(path) + 1;
- msg = cext_emallocz(*msg_len);
- h.req = TREMOVE;
- memcpy(msg, &h, sizeof(ReqHeader));
- memcpy(msg + sizeof(ReqHeader), path, strlen(path) + 1);
- return msg;
-}
+ if(msize > msglen)
+ return 0;
+ p = ixp_enc_prefix(p, msize, fcall->id, fcall->tag);
-void *rcreate_message(size_t * msg_len)
-{
- char *msg;
- ResHeader h;
- *msg_len = sizeof(ResHeader);
- msg = cext_emallocz(*msg_len);
- h.res = RCREATE;
- memcpy(msg, &h, sizeof(ResHeader));
- return msg;
-}
+ switch (fcall->id) {
+ case TVERSION:
+ case RVERSION:
+ p = ixp_enc_u32(p, fcall->maxmsg);
+ p = ixp_enc_string(p, fcall->version);
+ break;
+ case TAUTH:
+ p = ixp_enc_u32(p, fcall->afid);
+ p = ixp_enc_string(p, fcall->uname);
+ p = ixp_enc_string(p, fcall->aname);
+ break;
+ case RAUTH:
+ p = ixp_enc_qid(p, &fcall->aqid);
+ break;
+ case RATTACH:
+ p = ixp_enc_qid(p, &fcall->qid);
+ break;
+ case TATTACH:
+ p = ixp_enc_u32(p, fcall->fid);
+ p = ixp_enc_u32(p, fcall->afid);
+ p = ixp_enc_string(p, fcall->uname);
+ p = ixp_enc_string(p, fcall->aname);
+ break;
+ case RERROR:
+ p = ixp_enc_string(p, fcall->errstr);
+ break;
+ case TFLUSH:
+ p = ixp_enc_u16(p, fcall->oldtag);
+ break;
+ case TWALK:
+ p = ixp_enc_u32(p, fcall->fid);
+ p = ixp_enc_u32(p, fcall->newfid);
+ p = ixp_enc_u16(p, fcall->nwname);
+ for(i = 0; i < fcall->nwname; i++)
+ p = ixp_enc_string(p, fcall->wname[i]);
+ break;
+ case RWALK:
+ p = ixp_enc_u16(p, fcall->nwqid);
+ for(i = 0; i < fcall->nwqid; i++)
+ p = ixp_enc_qid(p, &fcall->wqid[i]);
+ break;
+ case TOPEN:
+ p = ixp_enc_u32(p, fcall->fid);
+ p = ixp_enc_u8(p, fcall->mode);
+ break;
+ case ROPEN:
+ case RCREATE:
+ p = ixp_enc_qid(p, &fcall->qid);
+ p = ixp_enc_u32(p, fcall->iounit);
+ break;
+ case TCREATE:
+ p = ixp_enc_u32(p, fcall->fid);
+ p = ixp_enc_string(p, fcall->name);
+ p = ixp_enc_u32(p, fcall->perm);
+ p = ixp_enc_u8(p, fcall->mode);
+ break;
+ case TREAD:
+ p = ixp_enc_u32(p, fcall->fid);
+ p = ixp_enc_u64(p, fcall->offset);
+ p = ixp_enc_u32(p, fcall->count);
+ break;
+ case RREAD:
+ p = ixp_enc_u32(p, fcall->count);
+ p = ixp_enc_data(p, fcall->data, fcall->count);
+ break;
+ case TWRITE:
+ p = ixp_enc_u32(p, fcall->fid);
+ p = ixp_enc_u64(p, fcall->offset);
+ p = ixp_enc_u32(p, fcall->count);
+ p = ixp_enc_data(p, fcall->data, fcall->count);
+ break;
+ case RWRITE:
+ p = ixp_enc_u32(p, fcall->count);
+ break;
+ case TCLUNK:
+ case TREMOVE:
+ case TSTAT:
+ p = ixp_enc_u32(p, fcall->fid);
+ break;
+ case RSTAT:
+ p = ixp_enc_u16(p, ixp_sizeof_stat(&fcall->stat));
+ p = ixp_enc_stat(p, &fcall->stat);
+ break;
+ case TWSTAT:
+ p = ixp_enc_u32(p, fcall->fid);
+ p = ixp_enc_u16(p, ixp_sizeof_stat(&fcall->stat));
+ p = ixp_enc_stat(p, &fcall->stat);
+ break;
+ }
-void *ropen_message(int fd, size_t * msg_len)
-{
- char *msg;
- ResHeader h;
- *msg_len = sizeof(ResHeader);
- msg = cext_emallocz(*msg_len);
- h.res = ROPEN;
- h.fd = fd;
- memcpy(msg, &h, sizeof(ResHeader));
- return msg;
+ if(msg + msize == p)
+ return msize;
+ return 0;
}
-void *rread_message(void *content, size_t content_len, size_t * msg_len)
+unsigned int
+ixp_msg_to_fcall(void *msg, unsigned int msglen, Fcall * fcall)
{
- char *msg;
- ResHeader h;
- *msg_len = sizeof(ResHeader) + content_len;
- msg = cext_emallocz(*msg_len);
- h.res = RREAD;
- h.buf_len = content_len;
- memcpy(msg, &h, sizeof(ResHeader));
- memmove(msg + sizeof(ResHeader), content, content_len);
- return msg;
-}
+ unsigned int i, msize;
+ unsigned short len;
+ void *p = ixp_dec_prefix(msg, &msize, &fcall->id, &fcall->tag);
-void *rwrite_message(size_t * msg_len)
-{
- char *msg;
- ResHeader h;
- *msg_len = sizeof(ResHeader);
- msg = cext_emallocz(*msg_len);
- h.res = RWRITE;
- memcpy(msg, &h, sizeof(ResHeader));
- return msg;
-}
+ if(msize > msglen) /* bad message */
+ return 0;
-void *rclose_message(size_t * msg_len)
-{
- char *msg;
- ResHeader h;
- *msg_len = sizeof(ResHeader);
- msg = cext_emallocz(*msg_len);
- h.res = RCLUNK;
- memcpy(msg, &h, sizeof(ResHeader));
- return msg;
-}
+ switch (fcall->id) {
+ case TVERSION:
+ case RVERSION:
+ p = ixp_dec_u32(p, &fcall->maxmsg);
+ p = ixp_dec_string(p, fcall->version, sizeof(fcall->version), &len);
+ break;
+ case TAUTH:
+ p = ixp_dec_u32(p, &fcall->afid);
+ p = ixp_dec_string(p, fcall->uname, sizeof(fcall->uname), &len);
+ p = ixp_dec_string(p, fcall->aname, sizeof(fcall->aname), &len);
+ break;
+ case RAUTH:
+ p = ixp_dec_qid(p, &fcall->aqid);
+ break;
+ case RATTACH:
+ p = ixp_dec_qid(p, &fcall->qid);
+ break;
+ case TATTACH:
+ p = ixp_dec_u32(p, &fcall->fid);
+ p = ixp_dec_u32(p, &fcall->afid);
+ p = ixp_dec_string(p, fcall->uname, sizeof(fcall->uname), &len);
+ p = ixp_dec_string(p, fcall->aname, sizeof(fcall->aname), &len);
+ break;
+ case RERROR:
+ p = ixp_dec_string(p, fcall->errstr, sizeof(fcall->errstr), &len);
+ break;
+ case TFLUSH:
+ p = ixp_dec_u16(p, &fcall->oldtag);
+ break;
+ case TWALK:
+ p = ixp_dec_u32(p, &fcall->fid);
+ p = ixp_dec_u32(p, &fcall->newfid);
+ p = ixp_dec_u16(p, &fcall->nwname);
+ for(i = 0; i < fcall->nwname; i++) {
-void *rremove_message(size_t * msg_len)
-{
- char *msg;
- ResHeader h;
- *msg_len = sizeof(ResHeader);
- msg = cext_emallocz(*msg_len);
- h.res = RREMOVE;
- memcpy(msg, &h, sizeof(ResHeader));
- return msg;
-}
+ p = ixp_dec_string(p, fcall->wname[i], IXP_MAX_FLEN, &len);
+ }
+ break;
+ case RWALK:
+ p = ixp_dec_u16(p, &fcall->nwqid);
+ for(i = 0; i < fcall->nwqid; i++)
+ p = ixp_dec_qid(p, &fcall->wqid[i]);
+ break;
+ case TOPEN:
+ p = ixp_dec_u32(p, &fcall->fid);
+ p = ixp_dec_u8(p, &fcall->mode);
+ break;
+ case ROPEN:
+ case RCREATE:
+ p = ixp_dec_qid(p, &fcall->qid);
+ p = ixp_dec_u32(p, &fcall->iounit);
+ break;
+ case TCREATE:
+ p = ixp_dec_u32(p, &fcall->fid);
+ p = ixp_dec_string(p, fcall->name, sizeof(fcall->name), &len);
+ p = ixp_dec_u32(p, &fcall->perm);
+ p = ixp_dec_u8(p, &fcall->mode);
+ break;
+ case TREAD:
+ p = ixp_dec_u32(p, &fcall->fid);
+ p = ixp_dec_u64(p, &fcall->offset);
+ p = ixp_dec_u32(p, &fcall->count);
+ break;
+ case RREAD:
+ p = ixp_dec_u32(p, &fcall->count);
+ p = ixp_dec_data(p, fcall->data, fcall->count);
+ break;
+ case TWRITE:
+ p = ixp_dec_u32(p, &fcall->fid);
+ p = ixp_dec_u64(p, &fcall->offset);
+ p = ixp_dec_u32(p, &fcall->count);
+ p = ixp_dec_data(p, fcall->data, fcall->count);
+ break;
+ case RWRITE:
+ p = ixp_dec_u32(p, &fcall->count);
+ break;
+ case TCLUNK:
+ case TREMOVE:
+ case TSTAT:
+ p = ixp_dec_u32(p, &fcall->fid);
+ break;
+ case RSTAT:
+ p = ixp_dec_u16(p, &len);
+ p = ixp_dec_stat(p, &fcall->stat);
+ break;
+ case TWSTAT:
+ p = ixp_dec_u32(p, &fcall->fid);
+ p = ixp_dec_u16(p, &len);
+ p = ixp_dec_stat(p, &fcall->stat);
+ break;
+ }
-void *rerror_message(char *errstr, size_t * msg_len)
-{
- char *msg;
- size_t len = strlen(errstr) + 1;
- ResHeader h;
- *msg_len = sizeof(ResHeader) + len;
- msg = cext_emallocz(*msg_len);
- h.res = RERROR;
- memcpy(msg, &h, sizeof(ResHeader));
- memmove(msg + sizeof(ResHeader), errstr, len);
- return msg;
+ if(msg + msize == p)
+ return msize;
+ return 0;
}
diff --git a/libixp/ramfs.c b/libixp/ramfs.c
@@ -1,297 +0,0 @@
-/*
- * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "ixp.h"
-
-#include <cext.h>
-
-int is_directory(File * f)
-{
- return !f->size && f->content;
-}
-
-File *ixp_create(IXPServer * s, char *path)
-{
- File *f, *p;
- char *buf = strdup(path);
- char *tok, *tok_ptr;
-
- if (!path)
- return 0;
-
- /* cannot create a directory with empty name */
- if (buf[strlen(buf) - 1] == '/')
- return 0;
- tok = strtok_r(buf, "/", &tok_ptr);
- p = s->root;
- f = p->content;
- /* first determine the path as it exists already */
- while (f && tok) {
- if (!strcmp(f->name, tok)) {
- tok = strtok_r(0, "/", &tok_ptr);
- p = f;
- if (tok && is_directory(f))
- f = f->content;
- else
- break;
- continue;
- }
- f = f->next;
- }
- if (p->size && tok) {
- free(buf);
- return 0; /* cannot create subdirectory, if file has
- * content */
- }
- /* only create missing parts, if file is directory */
- while (tok) {
- f = (File *) cext_emallocz(sizeof(File));
- f->name = strdup(tok);
- f->parent = p;
- if (p->content) {
- p = p->content;
- while (p->next) {
- p = p->next;
- }
- p->next = f;
- } else {
- p->content = f;
- }
- p = f;
- tok = strtok_r(0, "/", &tok_ptr);
- }
- free(buf);
- return f;
-}
-
-static int comp_file_name(const void *f1, const void *f2)
-{
- File *f = (File *) f1;
- File *p = (File *) f2;
- return strcmp(*(char **) f->name, *(char **) p->name);
-}
-
-static char *xls(File * f)
-{
- File *p;
- char *result = 0;
- size_t size = 1; /* for \n */
- int num = 0, i;
- File **tmp;
-
- for (p = f; p; p = p->next)
- num++;
- tmp = cext_emallocz(sizeof(File *) * num);
- i = 0;
- for (p = f; p; p = p->next) {
- size += strlen(p->name) + 1;
- if (is_directory(p))
- size++;
- tmp[i++] = p;
- }
- qsort(tmp, num, sizeof(File *), comp_file_name);
- result = cext_emallocz(size);
- for (i = 0; i < num; i++) {
- strncat(result, tmp[i]->name, size);
- if (is_directory(tmp[i]))
- strncat(result, "/\n", size);
- else
- strncat(result, "\n", size);
- }
- free(tmp);
- return result;
-}
-
-File *ixp_open(IXPServer * s, char *path)
-{
- File *f;
-
- f = ixp_walk(s, path);
- if (!f) {
- set_error(s, "file does not exist");
- return nil;
- }
- return f;
-}
-
-void ixp_close(IXPServer * s, int fd)
-{
- File *f = fd_to_file(s, fd);
- if (!f)
- set_error(s, "invalid file descriptor");
-}
-
-size_t
-ixp_read(IXPServer * s, int fd, size_t offset, void *out_buf,
- size_t out_buf_len)
-{
- File *f = fd_to_file(s, fd);
- void *result = 0;
- size_t len = 0, res_len = 0;
-
- if (!f) {
- set_error(s, "invalid file descriptor");
- return 0;
- }
- /* callback */
- if (f->before_read)
- f->before_read(s, f);
- if (is_directory(f)) {
- result = xls(f->content);
- res_len = strlen(result);
- } else if (f->size) {
- result = f->content;
- res_len = f->size;
- }
- if (offset > res_len) {
- set_error(s, "invalid offset when reading file");
- if (is_directory(f))
- free(result);
- return 0;
- }
- if (result) {
- len = res_len - offset;
- if (len > out_buf_len)
- len = out_buf_len;
- memcpy(out_buf, (char *) result + offset, len);
- if (is_directory(f))
- free(result);
- }
- return len;
-}
-
-void
-ixp_write(IXPServer * s, int fd, size_t offset, void *content,
- size_t in_len)
-{
- File *f = fd_to_file(s, fd);
-
- if (!f) {
- set_error(s, "invalid file descriptor");
- return;
- }
- if (is_directory(f)) {
- /* we cannot write to directories */
- set_error(s, "cannot write to a directory");
- return;
- }
- if (in_len) {
- /* offset 0 flushes the file */
- if (!offset || (offset + in_len > f->size)) {
- f->content = realloc(f->content, offset + in_len + 1);
- f->size = offset + in_len;
- }
- memcpy((char *) f->content + offset, content, in_len);
- /* internal EOF character */
- ((char *) f->content)[f->size] = 0;
- } else if (!offset) {
- /* blank file */
- if (f->content)
- free(f->content);
- f->content = 0;
- f->size = 0;
- }
- /* callback */
- if (f->after_write)
- f->after_write(s, f);
-}
-
-static void xremove(IXPServer * s, File * f)
-{
- if (!f)
- return;
- if (f->next) {
- xremove(s, f->next);
- if (s->errstr)
- return;
- }
- if (!f->bind && is_directory(f)) {
- xremove(s, f->content);
- if (s->errstr)
- return;
- }
- if (f->content && f->size) {
- free(f->content);
- }
- if (f != s->root) {
- if (f->name) {
- free(f->name);
- }
- free(f);
- }
-}
-
-void ixp_remove_file(IXPServer * s, File * f)
-{
- File *p, *n;
- set_error(s, 0);
- if (!f) {
- set_error(s, "file does not exist");
- return;
- }
- /* detach */
- p = f->parent;
- n = f->next;
- f->next = 0;
- if (p) {
- if (p->content == f)
- p->content = n;
- else {
- p = p->content;
- while (p && (p->next != f))
- p = p->next;
- if (p)
- p->next = n;
- }
- }
- /* remove now */
- xremove(s, f);
-}
-
-
-void ixp_remove(IXPServer * s, char *path)
-{
- ixp_remove_file(s, ixp_walk(s, path));
-}
-
-File *ixp_walk(IXPServer * s, char *path)
-{
- File *f = 0;
- File *n;
- char *buf;
- char *tok, *tok_ptr;
-
- if (!path) {
- return 0;
- }
- buf = strdup(path);
-
- tok = strtok_r(buf, "/", &tok_ptr);
- f = s->root->content;
- if (!tok && buf[0] == '/') {
- f = s->root;
- }
- while (f && tok) {
- n = f->next;
- if (!strcmp(f->name, tok)) {
- tok = strtok_r(0, "/", &tok_ptr);
- if (tok && f->size)
- return 0;
- if (!tok)
- break;
- f = f->content;
- continue;
- }
- f = n;
- }
- if (f && (path[strlen(path) - 1] == '/') && !is_directory(f))
- f = 0;
- free(buf);
- return f;
-}
diff --git a/libixp/server.c b/libixp/server.c
@@ -5,434 +5,69 @@
#include <errno.h>
#include <fcntl.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
-#include <signal.h>
#include <string.h>
-#include <sys/un.h>
#include <sys/stat.h>
#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
#include "ixp.h"
+#include "cext.h"
-#include <cext.h>
-
-static Connection zero_conn = { 0 };
-static int user_fd = -1;
-
-void set_error(IXPServer * s, char *errstr)
-{
- if (s->errstr)
- free(s->errstr);
- if (errstr)
- s->errstr = strdup(errstr);
- else
- s->errstr = 0;
-}
-
-File *fd_to_file(IXPServer * s, int fd)
-{
- int cidx = fd / MAX_CONN;
- int fidx = fd - (cidx * MAX_CONN);
-
- return s->conn[cidx].files[fidx];
-}
-
-static void handle_ixp_create(Connection * c)
-{
- c->s->create(c->s, ((char *) c->data) + sizeof(ReqHeader));
- free(c->data);
- c->data = c->s->errstr ?
- rerror_message(c->s->errstr, &c->len) : rcreate_message(&c->len);
- c->remain = c->len;
-}
-
-static void handle_ixp_open(Connection * c)
-{
- int i;
-
- /* seek next free slot */
- for (i = 0; (i < MAX_OPEN_FILES) && c->files[i]; i++);
- if (i == MAX_OPEN_FILES) {
- fprintf(stderr, "%s",
- "ixp: server: maximum of open files, try again later.\n");
- free(c->data);
- c->data =
- rerror_message("maximum open files reached, close files first",
- &c->len);
- c->remain = c->len;
- return;
- }
- c->files[i] = c->s->open(c->s, ((char *) c->data) + sizeof(ReqHeader));
- c->seen[i] = MAX_SEEN_SHUTDOWN;
- free(c->data);
- c->data = c->s->errstr ?
- rerror_message(c->s->errstr,
- &c->len) : ropen_message(i + MAX_CONN * c->index,
- &c->len);
- c->remain = c->len;
-}
-
-static void handle_ixp_read(Connection * c, ReqHeader * h)
-{
- void *data = 0;
- size_t out_len;
-
- data = cext_emallocz(h->buf_len);
- out_len = c->s->read(c->s, h->fd, h->offset, data, h->buf_len);
- free(c->data);
- if (c->s->errstr)
- c->data = rerror_message(c->s->errstr, &c->len);
- else
- c->data = rread_message(data, out_len, &c->len);
- c->remain = c->len;
- free(data);
-}
-
-static void handle_ixp_write(Connection * c, ReqHeader * h)
-{
- c->s->write(c->s, h->fd, h->offset,
- ((char *) c->data) + sizeof(ReqHeader), h->buf_len);
- free(c->data);
- if (c->s->errstr)
- c->data = rerror_message(c->s->errstr, &c->len);
- else
- c->data = rwrite_message(&c->len);
- c->remain = c->len;
-}
-
-static void handle_ixp_close(Connection * c, ReqHeader * h)
-{
- int fidx = h->fd - (c->index * MAX_CONN);
-
- c->s->close(c->s, h->fd);
- c->files[fidx] = 0;
- free(c->data);
- if (c->s->errstr)
- c->data = rerror_message(c->s->errstr, &c->len);
- else
- c->data = rclose_message(&c->len);
- c->remain = c->len;
-}
-
-static void handle_ixp_remove(Connection * c)
-{
- c->s->remove(c->s, ((char *) c->data) + sizeof(ReqHeader));
- free(c->data);
- c->data = c->s->errstr ?
- rerror_message(c->s->errstr, &c->len) : rremove_message(&c->len);
- c->remain = c->len;
-}
-
-static void check_ixp_request(Connection * c)
-{
- ReqHeader h;
- /* check pending request */
- if (c->s->errstr)
- set_error(c->s, 0);
- memcpy(&h, c->data, sizeof(ReqHeader));
- switch (h.req) {
- case TCREATE:
- handle_ixp_create(c);
- break;
- case TREMOVE:
- handle_ixp_remove(c);
- break;
- case TOPEN:
- handle_ixp_open(c);
- break;
- case TCLUNK:
- handle_ixp_close(c, &h);
- break;
- case TREAD:
- handle_ixp_read(c, &h);
- break;
- case TWRITE:
- handle_ixp_write(c, &h);
- break;
- default:
- fprintf(stderr, "%s", "ixp: server: invalid request\n");
- free(c->data);
- c->len = c->remain = 0;
- break;
- }
-}
-
-static void update_conns(IXPServer * s)
-{
- int i;
-
- FD_ZERO(&s->rd);
- FD_ZERO(&s->wr);
- for (i = 0; i < MAX_CONN; i++) {
- if (s->conn[i].fd >= 0) {
- s->nfds = xMAX(s->nfds, s->conn[i].fd);
- if (s->conn[i].read && !s->conn[i].mode
- && (!s->conn[i].len || s->conn[i].remain)) {
- FD_SET(s->conn[i].fd, &s->rd);
- }
- if (s->conn[i].write && s->conn[i].mode && s->conn[i].remain) {
- FD_SET(s->conn[i].fd, &s->wr);
- }
- }
- }
-}
-
-static void close_conn(Connection * c)
-{
- int i;
- /* shutdown connection and cleanup open files */
- shutdown(c->fd, SHUT_RDWR);
- close(c->fd);
- c->fd = -1;
- c->mode = 0;
- for (i = 0; i < MAX_OPEN_FILES; i++) {
- if (c->files[i])
- c->files[i] = 0;
- }
-}
-
-static void read_conn(Connection * c)
-{
- size_t r;
-
- if (!c->header) {
- r = read(c->fd, &c->len, sizeof(size_t));
- if (r != sizeof(size_t)) {
- close_conn(c);
- return;
- }
- c->remain = c->len;
- c->data = cext_emallocz(c->len);
- c->header = 1;
- }
- r = read(c->fd, ((char *) c->data) + c->len - c->remain, c->remain);
- if (r < 1) {
- close_conn(c);
- return;
- }
- c->remain -= r;
-
- if (c->remain == 0) {
- /* check IXP request */
- c->mode = 1; /* next mode is response */
- check_ixp_request(c);
- c->header = 0;
- }
-}
-
-static void write_conn(Connection * c)
-{
- size_t r;
-
- if (!c->header) {
- r = write(c->fd, &c->len, sizeof(size_t));
- if (r != sizeof(size_t)) {
- close_conn(c);
- }
- c->header = 1;
- }
- r = write(c->fd, ((char *) c->data) + c->len - c->remain, c->remain);
- if (r < 1) {
- close_conn(c);
- return;
- }
- c->remain -= r;
-
- if (c->remain == 0) {
- c->len = 0;
- c->mode = 0;
- c->header = 0;
- }
-}
-
-static void new_conn(Connection * c)
+static void
+prepare_select(IXPServer *s)
{
- int r, i;
- socklen_t l;
- struct sockaddr_un name = { 0 };
-
- l = sizeof(name);
- if ((r = accept(c->fd, (struct sockaddr *) &name, &l)) < 0) {
- perror("ixp: server: cannot accept connection");
- return;
- }
- if (c->s->runlevel == SHUTDOWN) {
- fprintf(stderr, "%s",
- "ixp: server: connection refused, server is shutting down.\n");
- close(r);
- return;
- }
- for (i = 0; i < MAX_CONN; i++) {
- if (c->s->conn[i].fd == -1) { /* free connection */
- c->s->conn[i] = zero_conn;
- c->s->conn[i].s = c->s;
- c->s->conn[i].index = i;
- c->s->conn[i].fd = r;
- c->s->conn[i].read = read_conn;
- c->s->conn[i].write = write_conn;
- break;
- }
- }
-
- if (i == MAX_CONN) {
- fprintf(stderr, "%s",
- "ixp: server: connection refused, try again later.\n");
- close(r);
- }
-}
-
-
-static int check_open_files(Connection * c)
-{
- int i;
- for (i = 0; i < MAX_OPEN_FILES; i++) {
- if (c->files[i] && c->seen[i]) {
- c->seen[i]--;
- return 1;
- }
- }
- return 0;
-}
-
-static void handle_socks(IXPServer * s)
-{
- int i, now = 1;
- for (i = 0; i < MAX_CONN; i++) {
- if (s->conn[i].fd >= 0) {
- if (FD_ISSET(s->conn[i].fd, &s->rd) && s->conn[i].read) {
- /* call back read handler */
- s->conn[i].read(&s->conn[i]);
- } else if (FD_ISSET(s->conn[i].fd, &s->wr) && s->conn[i].write) {
- /* call back write handler */
- s->conn[i].write(&s->conn[i]);
- }
- /*
- * don't shutdown, if there're remaining bits or if
- * still responses are sent or still opened files
- */
- if ((s->runlevel == SHUTDOWN)
- && (check_open_files(&s->conn[i])
- || (s->conn[i].remain > 0)
- || s->conn[i].mode))
- now = 0;
- }
- }
- if ((s->runlevel == SHUTDOWN) && now)
- s->runlevel = HALT; /* real stop */
-}
-
-IXPServer *init_server(char *sockfile, void (*cleanup) (void))
-{
- int i;
- struct sockaddr_un addr = { 0 };
- int yes = 1;
- socklen_t su_len;
- IXPServer *s;
-
- /* init */
- s = (IXPServer *) cext_emallocz(sizeof(IXPServer));
- s->sockfile = sockfile;
- s->root = (File *) cext_emallocz(sizeof(File));
- s->runlevel = HALT; /* initially server is not running */
- s->create = ixp_create;
- s->remove = ixp_remove;
- s->open = ixp_open;
- s->close = ixp_close;
- s->read = ixp_read;
- s->write = ixp_write;
- s->root->name = strdup("");
- for (i = 0; i < MAX_CONN; i++) {
- s->conn[i].s = s;
- s->conn[i].fd = -1;
- s->conn[i].index = i;
- }
-
- signal(SIGPIPE, SIG_IGN);
- if ((s->conn[0].fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
- perror("ixp: server: socket");
- free(s);
- return 0;
- }
- if (setsockopt(s->conn[0].fd, SOL_SOCKET, SO_REUSEADDR,
- (char *) &yes, sizeof(yes)) < 0) {
- perror("ixp: server: setsockopt");
- close(s->conn[0].fd);
- free(s);
- return 0;
- }
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, sockfile, sizeof(addr.sun_path));
- su_len = sizeof(struct sockaddr) + strlen(addr.sun_path);
-
- if (bind(s->conn[0].fd, (struct sockaddr *) &addr, su_len) < 0) {
- perror("ixp: server: cannot bind socket");
- close(s->conn[0].fd);
- free(s);
- return 0;
- }
- chmod(sockfile, S_IRWXU);
-
- if (listen(s->conn[0].fd, MAX_CONN) < 0) {
- perror("ixp: server: cannot listen on socket");
- close(s->conn[0].fd);
- free(s);
- return 0;
- }
- s->conn[0].read = new_conn;
-
- /* register to cleanup function, to unlink sockfile */
- if (cleanup)
- atexit(cleanup);
-
- return s;
+ int i;
+ FD_ZERO(&s->rd);
+ for(i = 0; (i < s->connsz) && s->conn[i]; i++) {
+ if(s->maxfd < s->conn[i]->fd)
+ s->maxfd = s->conn[i]->fd;
+ if(s->conn[i]->read)
+ FD_SET(s->conn[i]->fd, &s->rd);
+ }
}
-void
-run_server_with_fd_support(IXPServer * s, int fd,
- void (*fd_read) (Connection *),
- void (*fd_write) (Connection *))
+static void
+handle_conns(IXPServer *s)
{
- s->conn[1] = zero_conn;
- s->conn[1].index = 1;
- s->conn[1].s = s;
- s->conn[1].fd = user_fd = fd;
- s->conn[1].read = fd_read;
- s->conn[1].write = fd_write;
- run_server(s);
+ int i;
+ for(i = 0; (i < s->connsz) && s->conn[i]; i++)
+ if(FD_ISSET(s->conn[i]->fd, &s->rd) && s->conn[i]->read)
+ /* call read handler */
+ s->conn[i]->read(s, s->conn[i]);
}
-void run_server(IXPServer * s)
+char *
+ixp_server_loop(IXPServer *s)
{
- int r, i;
- s->runlevel = RUNNING;
+ int r;
+ s->running = 1;
- /* main loop */
- while (s->runlevel != HALT) {
+ /* main loop */
+ while(s->running && s->conn) {
- update_conns(s);
+ prepare_select(s);
- r = select(s->nfds + 1, &s->rd, &s->wr, 0, 0);
- if (r == -1 && errno == EINTR)
- continue;
- if (r < 0) {
- perror("ixp: server: select");
- break; /* allow cleanups in IXP using app */
- } else if (r > 0) {
- handle_socks(s);
- }
- }
- /* shut down server */
- for (i = MAX_CONN - 1; i >= 0; i--) {
- if (s->conn[i].fd >= 0 && s->conn[i].fd != user_fd) {
- close(s->conn[i].fd);
- }
- }
+ r = select(s->maxfd + 1, &s->rd, 0, 0, 0);
+ if(r == -1 && errno == EINTR)
+ continue;
+ if(r < 0)
+ return "fatal select error";
+ else if(r > 0)
+ handle_conns(s);
+ }
+ return nil;
}
-void deinit_server(IXPServer * s)
+IXPMap *
+ixp_server_fid2map(IXPConn *c, unsigned int fid)
{
- unlink(s->sockfile);
- ixp_remove(s, "/");
- free(s);
+ size_t i;
+ for(i = 0; (i < c->mapsz) && c->map[i]; i++)
+ if(c->map[i]->fid == fid)
+ return c->map[i];
+ return nil;
}
diff --git a/libixp/socket.c b/libixp/socket.c
@@ -0,0 +1,204 @@
+/*
+ * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
+ * See LICENSE file for license details.
+ */
+
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "cext.h"
+#include "ixp.h"
+
+static int
+connect_unix_sock(char *address)
+{
+ int fd = 0;
+ struct sockaddr_un addr = { 0 };
+ socklen_t su_len;
+
+ /* init */
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, address, sizeof(addr.sun_path));
+ su_len = sizeof(struct sockaddr) + strlen(addr.sun_path);
+
+ if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ return -1;
+ if(connect(fd, (struct sockaddr *) &addr, su_len)) {
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+static int
+connect_inet_sock(char *host)
+{
+ int fd = 0;
+ struct sockaddr_in addr = { 0 };
+ struct hostent *hp;
+ char *port = strrchr(host, '!');
+ const char *errstr = nil;
+ unsigned int prt;
+
+ *port = 0;
+ port++;
+ prt = cext_strtonum(port, 1024, 65535, &errstr);
+ if(errstr)
+ return -1;
+
+ /* init */
+ if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ return -1;
+ hp = gethostbyname(host);
+ addr.sin_family = AF_INET;
+ addr.sin_port = htons(prt);
+ bcopy(hp->h_addr, &addr.sin_addr, hp->h_length);
+
+ if(connect(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in))) {
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+int
+ixp_connect_sock(char *address)
+{
+ char *p = strchr(address, '!');
+ char *addr, *type;
+
+ if(!p)
+ return -1;
+ *p = 0;
+
+ addr = &p[1];
+ type = address; /* unix, inet */
+
+ if(!strncmp(type, "unix", 5))
+ return connect_unix_sock(addr);
+ else if(!strncmp(type, "tcp", 4))
+ return connect_inet_sock(addr);
+ return -1;
+}
+
+int
+ixp_accept_sock(int fd)
+{
+ socklen_t su_len;
+ struct sockaddr_un addr = { 0 };
+
+ su_len = sizeof(struct sockaddr);
+ return accept(fd, (struct sockaddr *) &addr, &su_len);
+}
+
+static int
+create_inet_sock(char *host, char **errstr)
+{
+ int fd;
+ struct sockaddr_in addr = { 0 };
+ char *port = strrchr(host, '!');
+ unsigned int prt;
+
+ if(!port) {
+ *errstr = "no port provided in address";
+ return -1;
+ }
+ *port = 0;
+ port++;
+ prt = cext_strtonum(port, 1024, 65535, (const char **)errstr);
+ if(*errstr)
+ return -1;
+ signal(SIGPIPE, SIG_IGN);
+ if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ *errstr = "cannot open socket";
+ return -1;
+ }
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ addr.sin_port = htons(prt);
+
+ if(bind(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) < 0) {
+ *errstr = "cannot bind socket";
+ close(fd);
+ return -1;
+ }
+
+ if(listen(fd, IXP_MAX_CACHE) < 0) {
+ *errstr = "cannot listen on socket";
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+static int
+create_unix_sock(char *file, char **errstr)
+{
+ int fd;
+ int yes = 1;
+ struct sockaddr_un addr = { 0 };
+ socklen_t su_len;
+
+ signal(SIGPIPE, SIG_IGN);
+ if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+ *errstr = "cannot open socket";
+ return -1;
+ }
+ if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
+ (char *) &yes, sizeof(yes)) < 0) {
+ *errstr = "cannot set socket options";
+ close(fd);
+ return -1;
+ }
+ addr.sun_family = AF_UNIX;
+ strncpy(addr.sun_path, file, sizeof(addr.sun_path));
+ su_len = sizeof(struct sockaddr) + strlen(addr.sun_path);
+
+ unlink(file); /* remove old socket, if any */
+ if(bind(fd, (struct sockaddr *) &addr, su_len) < 0) {
+ *errstr = "cannot bind socket";
+ close(fd);
+ return -1;
+ }
+ chmod(file, S_IRWXU);
+
+ if(listen(fd, IXP_MAX_CACHE) < 0) {
+ *errstr = "cannot listen on socket";
+ close(fd);
+ return -1;
+ }
+ return fd;
+}
+
+int
+ixp_create_sock(char *address, char **errstr)
+{
+ char *p = strchr(address, '!');
+ char *addr, *type;
+
+ if(!p) {
+ *errstr = "no socket type defined";
+ return -1;
+ }
+ *p = 0;
+
+ addr = &p[1];
+ type = address; /* unix, inet */
+
+ if(!strncmp(type, "unix", 5))
+ return create_unix_sock(addr, errstr);
+ else if(!strncmp(type, "tcp", 4))
+ return create_inet_sock(addr, errstr);
+ else
+ *errstr = "unkown socket type";
+ return -1;
+}
diff --git a/libixp/transport.c b/libixp/transport.c
@@ -0,0 +1,81 @@
+/*
+ * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
+ * See LICENSE file for license details.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#include "ixp.h"
+
+#include <cext.h>
+
+unsigned int
+ixp_send_message(int fd, void *msg, unsigned int msize, char **errstr)
+{
+ unsigned int num = 0;
+ int r;
+
+ /* send message */
+ while(num < msize) {
+ r = write(fd, msg + num, msize - num);
+ if(r == -1 && errno == EINTR)
+ continue;
+ if(r < 1) {
+ *errstr = "cannot send message";
+ return 0;
+ }
+ num += r;
+ }
+ return num;
+}
+
+static unsigned int
+ixp_recv_data(int fd, void *msg, unsigned int msize, char **errstr)
+{
+ unsigned int num = 0;
+ int r = 0;
+
+ /* receive data */
+ while(num < msize) {
+ r = read(fd, msg + num, msize - num);
+ if(r == -1 && errno == EINTR)
+ continue;
+ if(r < 1) {
+ *errstr = "cannot receive data";
+ return 0;
+ }
+ num += r;
+ }
+ return num;
+}
+
+unsigned int
+ixp_recv_message(int fd, void *msg, unsigned int msglen, char **errstr)
+{
+ unsigned int msize;
+
+ /* receive header */
+ if(ixp_recv_data(fd, msg, sizeof(unsigned int), errstr) !=
+ sizeof(unsigned int))
+ return 0;
+ ixp_dec_u32(msg, &msize);
+ if(msize > msglen) {
+ *errstr = "message size exceeds buffer size";
+ return 0;
+ }
+ /* receive message */
+ if(ixp_recv_data
+ (fd, msg + sizeof(unsigned int), msize - sizeof(unsigned int),
+ errstr)
+ != msize - sizeof(unsigned int))
+ return 0;
+ return msize;
+}
diff --git a/libixp2/Makefile b/libixp2/Makefile
@@ -1,25 +0,0 @@
-# libixp - lib ixp protocol
-# (C)opyright MMIV-MMVI Anselm R. Garbe
-
-include ../config.mk
-
-CFLAGS += -I ../libcext
-
-SRC = client.c convert.c message.c server.c socket.c transport.c
-
-OBJ = ${SRC:.c=.o}
-
-all: libixp
- @echo built libixp2
-
-.c.o:
- @echo CC $<
- @${CC} -c ${CFLAGS} $<
-
-libixp: ${OBJ}
- @echo AR $@.a
- @${AR} $@.a ${OBJ}
- @${RANLIB} $@.a
-
-clean:
- rm -f libixp.a *.o
diff --git a/libixp2/client.c b/libixp2/client.c
@@ -1,194 +0,0 @@
-/*
- * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include "cext.h"
-#include "ixp.h"
-
-static unsigned char msg[IXP_MAX_MSG];
-
-static int
-do_fcall(IXPClient * c)
-{
- unsigned int msize = ixp_fcall_to_msg(&c->fcall, msg, IXP_MAX_MSG);
- c->errstr = 0;
- if(ixp_send_message(c->fd, msg, msize, &c->errstr) != msize)
- return -1;
- if(!ixp_recv_message(c->fd, msg, IXP_MAX_MSG, &c->errstr))
- return -1;
- if(!(msize = ixp_msg_to_fcall(msg, IXP_MAX_MSG, &c->fcall))) {
- c->errstr = "received bad message";
- return -1;
- }
- if(c->fcall.id == RERROR) {
- c->errstr = c->fcall.errstr;
- return -1;
- }
- return 0;
-}
-
-int
-ixp_client_init(IXPClient * c, char *sockfile)
-{
- if((c->fd = ixp_connect_sock(sockfile)) < 0) {
- c->errstr = "cannot connect server";
- return -1;
- }
- /* version */
- c->fcall.id = TVERSION;
- c->fcall.tag = IXP_NOTAG;
- c->fcall.maxmsg = IXP_MAX_MSG;
- cext_strlcpy(c->fcall.version, IXP_VERSION, sizeof(c->fcall.version));
- if(do_fcall(c) == -1) {
- ixp_client_deinit(c);
- return -1;
- }
- if(strncmp(c->fcall.version, IXP_VERSION, strlen(IXP_VERSION))) {
- c->errstr = "9P versions differ";
- ixp_client_deinit(c);
- return -1; /* we cannot handle this version */
- }
- c->root_fid = getpid();
-
- /* attach */
- c->fcall.id = TATTACH;
- c->fcall.tag = IXP_NOTAG;
- c->fcall.fid = c->root_fid;
- c->fcall.afid = IXP_NOFID;
- cext_strlcpy(c->fcall.uname, getenv("USER"), sizeof(c->fcall.uname));
- c->fcall.aname[0] = 0;
- if(do_fcall(c) == -1) {
- ixp_client_deinit(c);
- return -1;
- }
- c->root_qid = c->fcall.qid;
- return 0;
-}
-
-int
-ixp_client_remove(IXPClient * c, unsigned int newfid, char *filepath)
-{
- if(ixp_client_walk(c, newfid, filepath) == -1)
- return -1;
- /* remove */
- c->fcall.id = TREMOVE;
- c->fcall.tag = IXP_NOTAG;
- c->fcall.fid = newfid;
- return do_fcall(c);
-}
-
-int
-ixp_client_create(IXPClient * c, unsigned int dirfid, char *name,
- unsigned int perm, unsigned char mode)
-{
- /* create */
- c->fcall.id = TCREATE;
- c->fcall.tag = IXP_NOTAG;
- c->fcall.fid = dirfid;
- cext_strlcpy(c->fcall.name, name, sizeof(c->fcall.name));
- c->fcall.perm = perm;
- c->fcall.mode = mode;
- return do_fcall(c);
-}
-
-int
-ixp_client_walk(IXPClient * c, unsigned int newfid, char *filepath)
-{
- unsigned int i;
- char *wname[IXP_MAX_WELEM];
- /* walk */
- c->fcall.id = TWALK;
- c->fcall.fid = c->root_fid;
- c->fcall.newfid = newfid;
- if(filepath) {
- cext_strlcpy(c->fcall.name, filepath, sizeof(c->fcall.name));
- c->fcall.nwname =
- cext_tokenize(wname, IXP_MAX_WELEM, c->fcall.name, '/');
- for(i = 0; i < c->fcall.nwname; i++)
- cext_strlcpy(c->fcall.wname[i], wname[i], sizeof(c->fcall.wname[i]));
- }
- return do_fcall(c);
-}
-
-int
-ixp_client_open(IXPClient * c, unsigned int newfid, char *filepath,
- unsigned char mode)
-{
- if(ixp_client_walk(c, newfid, filepath) == -1)
- return -1;
-
- /* open */
- c->fcall.id = TOPEN;
- c->fcall.tag = IXP_NOTAG;
- c->fcall.fid = newfid;
- c->fcall.mode = mode;
- return do_fcall(c);
-}
-
-int
-ixp_client_read(IXPClient * c, unsigned int fid, unsigned long long offset,
- void *result, unsigned int res_len)
-{
- unsigned int bytes = c->fcall.iounit;
-
- /* read */
- c->fcall.id = TREAD;
- c->fcall.tag = IXP_NOTAG;
- c->fcall.fid = fid;
- c->fcall.offset = offset;
- c->fcall.count = res_len < bytes ? res_len : bytes;
- if(do_fcall(c) == -1)
- return -1;
- memcpy(result, c->fcall.data, c->fcall.count);
- return c->fcall.count;
-}
-
-int
-ixp_client_write(IXPClient * c, unsigned int fid,
- unsigned long long offset, unsigned int count,
- unsigned char *data)
-{
- if(count > c->fcall.iounit)
- {
- c->errstr = "iounit exceeded";
- return -1;
- }
- /* write */
- c->fcall.id = TWRITE;
- c->fcall.tag = IXP_NOTAG;
- c->fcall.fid = fid;
- c->fcall.offset = offset;
- c->fcall.count = count;
- memcpy(c->fcall.data, data, count);
- if(do_fcall(c) == -1)
- return -1;
- return c->fcall.count;
-}
-
-int
-ixp_client_close(IXPClient * c, unsigned int fid)
-{
- /* clunk */
- c->fcall.id = TCLUNK;
- c->fcall.tag = IXP_NOTAG;
- c->fcall.fid = fid;
- return do_fcall(c);
-}
-
-void
-ixp_client_deinit(IXPClient * c)
-{
- /* session finished, now shutdown */
- if(c->fd) {
- shutdown(c->fd, SHUT_RDWR);
- close(c->fd);
- }
-}
diff --git a/libixp2/convert.c b/libixp2/convert.c
@@ -1,197 +0,0 @@
-/*
- * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include "ixp.h"
-
-/* encode/decode stuff */
-
-void *
-ixp_enc_u8(unsigned char *msg, unsigned char val)
-{
- msg[0] = val;
- return &msg[1];
-}
-
-void *
-ixp_dec_u8(unsigned char *msg, unsigned char *val)
-{
- *val = msg[0];
- return &msg[1];
-}
-
-void *
-ixp_enc_u16(unsigned char *msg, unsigned short val)
-{
- msg[0] = val;
- msg[1] = val >> 8;
- return &msg[2];
-}
-
-void *
-ixp_dec_u16(unsigned char *msg, unsigned short *val)
-{
- *val = msg[0] | (msg[1] << 8);
- return &msg[2];
-}
-
-void *
-ixp_enc_u32(unsigned char *msg, unsigned int val)
-{
- msg[0] = val;
- msg[1] = val >> 8;
- msg[2] = val >> 16;
- msg[3] = val >> 24;
- return &msg[4];
-}
-
-void *
-ixp_dec_u32(unsigned char *msg, unsigned int *val)
-{
- *val = msg[0] | (msg[1] << 8) | (msg[2] << 16) | (msg[3] << 24);
- return &msg[4];
-}
-
-void *
-ixp_enc_u64(unsigned char *msg, unsigned long long val)
-{
- msg[0] = val;
- msg[1] = val >> 8;
- msg[2] = val >> 16;
- msg[3] = val >> 24;
- msg[4] = val >> 32;
- msg[5] = val >> 40;
- msg[6] = val >> 48;
- msg[7] = val >> 56;
- return &msg[8];
-}
-
-void *
-ixp_dec_u64(unsigned char *msg, unsigned long long *val)
-{
- *val =
- (unsigned long long) msg[0] | ((unsigned long long) msg[1] << 8) |
- ((unsigned long long) msg[2] << 16) | ((unsigned long long) msg[3]
- << 24) | ((unsigned long
- long) msg[4] <<
- 32) | ((unsigned
- long long)
- msg[5] <<
- 40) |
- ((unsigned long long) msg[6] << 48) | ((unsigned long long) msg[7]
- << 56);
- return &msg[8];
-}
-
-void *
-ixp_enc_string(unsigned char *msg, const char *s)
-{
- unsigned short len = s ? strlen(s) : 0;
- msg = ixp_enc_u16(msg, len);
- if(s)
- memcpy(msg, s, len);
- return &msg[len];
-}
-
-void *
-ixp_dec_string(unsigned char *msg, char *string, unsigned short stringlen,
- unsigned short *len)
-{
- msg = ixp_dec_u16(msg, len);
- if(!(*len))
- return msg;
- if(*len > stringlen - 1)
- /* might never happen if stringlen == IXP_MAX_MSG */
- string[0] = 0;
- else {
- memcpy(string, msg, *len);
- string[*len] = 0;
- }
- return &msg[*len];
-}
-
-void *
-ixp_enc_data(unsigned char *msg, unsigned char *data, unsigned int datalen)
-{
- memcpy(msg, data, datalen);
- return &msg[datalen];
-}
-
-void *
-ixp_dec_data(unsigned char *msg, unsigned char *data, unsigned int datalen)
-{
- memcpy(data, msg, datalen);
- return &msg[datalen];
-}
-
-void *
-ixp_enc_prefix(unsigned char *msg, unsigned int size, unsigned char id,
- unsigned short tag)
-{
- msg = ixp_enc_u32(msg, size);
- msg = ixp_enc_u8(msg, id);
- return ixp_enc_u16(msg, tag);
-}
-
-void *
-ixp_dec_prefix(unsigned char *msg, unsigned int *size, unsigned char *id,
- unsigned short *tag)
-{
- msg = ixp_dec_u32(msg, size);
- msg = ixp_dec_u8(msg, id);
- return ixp_dec_u16(msg, tag);
-}
-
-void *
-ixp_enc_qid(unsigned char *msg, Qid * qid)
-{
- msg = ixp_enc_u8(msg, qid->type);
- msg = ixp_enc_u32(msg, qid->version);
- return ixp_enc_u64(msg, qid->path);
-}
-
-void *
-ixp_dec_qid(unsigned char *msg, Qid * qid)
-{
- msg = ixp_dec_u8(msg, &qid->type);
- msg = ixp_dec_u32(msg, &qid->version);
- return ixp_dec_u64(msg, &qid->path);
-}
-
-void *
-ixp_enc_stat(unsigned char *msg, Stat * stat)
-{
- msg = ixp_enc_u16(msg, ixp_sizeof_stat(stat) - sizeof(unsigned short));
- msg = ixp_enc_u16(msg, stat->type);
- msg = ixp_enc_u32(msg, stat->dev);
- msg = ixp_enc_qid(msg, &stat->qid);
- msg = ixp_enc_u32(msg, stat->mode);
- msg = ixp_enc_u32(msg, stat->atime);
- msg = ixp_enc_u32(msg, stat->mtime);
- msg = ixp_enc_u64(msg, stat->length);
- msg = ixp_enc_string(msg, stat->name);
- msg = ixp_enc_string(msg, stat->uid);
- msg = ixp_enc_string(msg, stat->gid);
- return ixp_enc_string(msg, stat->muid);
-}
-
-void *
-ixp_dec_stat(unsigned char *msg, Stat * stat)
-{
- unsigned short dummy;
- msg += sizeof(unsigned short);
- msg = ixp_dec_u16(msg, &stat->type);
- msg = ixp_dec_u32(msg, &stat->dev);
- msg = ixp_dec_qid(msg, &stat->qid);
- msg = ixp_dec_u32(msg, &stat->mode);
- msg = ixp_dec_u32(msg, &stat->atime);
- msg = ixp_dec_u32(msg, &stat->mtime);
- msg = ixp_dec_u64(msg, &stat->length);
- msg = ixp_dec_string(msg, stat->name, sizeof(stat->name), &dummy);
- msg = ixp_dec_string(msg, stat->uid, sizeof(stat->uid), &dummy);
- msg = ixp_dec_string(msg, stat->gid, sizeof(stat->gid), &dummy);
- return ixp_dec_string(msg, stat->muid, sizeof(stat->muid), &dummy);
-}
diff --git a/libixp2/ixp.h b/libixp2/ixp.h
@@ -1,289 +0,0 @@
-/*
- *(C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
- *See LICENSE file for license details.
- */
-
-#include <sys/types.h>
-
-#ifndef nil
-#define nil 0
-#endif
-
-#define IXP_VERSION "9P2000"
-#define IXP_MAX_VERSION 32
-#define IXP_MAX_ERROR 128
-#define IXP_MAX_CACHE 32
-#define IXP_MAX_MSG 8192
-#define IXP_MAX_FLEN 128
-#define IXP_MAX_ULEN 32
-#define IXP_MAX_STAT 64
-#define IXP_MAX_WELEM 16 /*MAXWELEM */
-#define IXP_MAX_TFUNCS 14
-
-
-/*
- size[4] Tversion tag[2] msize[4] version[s]
- size[4] Rversion tag[2] msize[4] version[s]
- size[4] Tauth tag[2] afid[4] uname[s] aname[s]
- size[4] Rauth tag[2] aqid[13]
- size[4] Rerror tag[2] ename[s]
- size[4] Tflush tag[2] oldtag[2]
- size[4] Rflush tag[2]
- size[4] Tattach tag[2] fid[4] afid[4] uname[s] aname[s]
- size[4] Rattach tag[2] qid[13]
- size[4] Twalk tag[2] fid[4] newfid[4] nwname[2] nwname*(wname[s])
- size[4] Rwalk tag[2] nwqid[2] nwqid*(wqid[13])
- size[4] Topen tag[2] fid[4] mode[1]
- size[4] Ropen tag[2] qid[13] iounit[4]
- size[4] Tcreate tag[2] fid[4] name[s] perm[4] mode[1]
- size[4] Rcreate tag[2] qid[13] iounit[4]
- size[4] Tread tag[2] fid[4] offset[8] count[4]
- size[4] Rread tag[2] count[4] data[count]
- size[4] Twrite tag[2] fid[4] offset[8] count[4] data[count]
- size[4] Rwrite tag[2] count[4]
- size[4] Tclunk tag[2] fid[4]
- size[4] Rclunk tag[2]
- size[4] Tremove tag[2] fid[4]
- size[4] Rremove tag[2]
- size[4] Tstat tag[2] fid[4]
- size[4] Rstat tag[2] stat[n]
- size[4] Twstat tag[2] fid[4] stat[n]
- size[4] Rwstat tag[2]
-
- stat[n]:
- size[2] total byte count of the following data
- type[2] for kernel use
- dev[4] for kernel use
- qid.type[1] the type of the file (directory, etc.),
- represented as a bit vector corresponding to the high 8 bits of the file's mode word.
- qid.vers[4] version number for given path
- qid.path[8] the file server's unique identification for the file
- mode[4] permissions and flags
- atime[4] last access time
- mtime[4] last modification time
- length[8] length of file in bytes
- name[ s ] file name; must be / if the file is the root directory of the server
- uid[ s ] owner name
- gid[ s ] group name
- muid[ s ]
-*/
-
-/*9P message types */
-enum {
- TVERSION = 100,
- RVERSION,
- TAUTH = 102,
- RAUTH,
- TATTACH = 104,
- RATTACH,
- TERROR = 106,
- RERROR,
- TFLUSH = 108,
- RFLUSH,
- TWALK = 110,
- RWALK,
- TOPEN = 112,
- ROPEN,
- TCREATE = 114,
- RCREATE,
- TREAD = 116,
- RREAD,
- TWRITE = 118,
- RWRITE,
- TCLUNK = 120,
- RCLUNK,
- TREMOVE = 122,
- RREMOVE,
- TSTAT = 124,
- RSTAT,
- TWSTAT = 126,
- RWSTAT,
-};
-
-/*borrowed from libc.h of Plan 9 */
-#define DMDIR 0x80000000 /*mode bit for directories */
-#define DMAPPEND 0x40000000 /*mode bit for append only files */
-#define DMEXCL 0x20000000 /*mode bit for exclusive use files */
-#define DMMOUNT 0x10000000 /*mode bit for mounted channel */
-#define DMAUTH 0x08000000 /*mode bit for authentication file */
-#define DMTMP 0x04000000 /*mode bit for non-backed-up file */
-
-#define DMREAD 0x4<<6 /*mode bit for read permission */
-#define DMWRITE 0x2<<6 /*mode bit for write permission */
-#define DMEXEC 0x1<<6 /*mode bit for execute permission */
-
-/*modes */
-enum {
- IXP_OREAD = 0x00,
- IXP_OWRITE = 0x01,
- IXP_ORDWR = 0x02,
- IXP_OEXEC = 0x03,
- IXP_OEXCL = 0x04,
- IXP_OTRUNC = 0x10,
- IXP_OREXEC = 0x20,
- IXP_ORCLOSE = 0x40,
- IXP_OAPPEND = 0x80,
-};
-
-/*qid.types */
-enum {
- IXP_QTDIR = 0x80,
- IXP_QTAPPEND = 0x40,
- IXP_QTEXCL = 0x20,
- IXP_QTMOUNT = 0x10,
- IXP_QTAUTH = 0x08,
- IXP_QTTMP = 0x04,
- IXP_QTSYMLINK = 0x02,
- IXP_QTLINK = 0x01,
- IXP_QTFILE = 0x00,
-};
-
-#define IXP_NOTAG (unsigned short)~0U /*Dummy tag */
-#define IXP_NOFID (unsigned int)~0 /*No auth */
-
-typedef struct {
- unsigned char type;
- unsigned int version;
- unsigned long long path;
-} Qid;
-
-/*stat structure */
-typedef struct {
- unsigned short type;
- unsigned int dev;
- Qid qid;
- unsigned int mode;
- unsigned int atime;
- unsigned int mtime;
- unsigned long long length;
- char name[IXP_MAX_FLEN];
- char uid[IXP_MAX_ULEN];
- char gid[IXP_MAX_ULEN];
- char muid[IXP_MAX_ULEN];
-} Stat;
-
-typedef struct {
- unsigned char id;
- unsigned short tag;
- unsigned int fid;
- unsigned int maxmsg; /*Tversion, Rversion */
- char version[IXP_MAX_VERSION]; /*Tversion, Rversion */
- unsigned short oldtag; /*Tflush */
- char errstr[IXP_MAX_ERROR]; /*Rerror */
- Qid qid; /*Rattach, Ropen, Rcreate */
- unsigned int iounit; /*Ropen, Rcreate */
- Qid aqid; /*Rauth */
- unsigned int afid; /*Tauth, Tattach */
- char uname[IXP_MAX_ULEN]; /*Tauth, Tattach */
- char aname[IXP_MAX_FLEN]; /*Tauth, Tattach */
- unsigned int perm; /*Tcreate */
- char name[IXP_MAX_FLEN]; /*Tcreate */
- unsigned char mode; /*Tcreate, Topen */
- unsigned int newfid; /*Twalk */
- unsigned short nwname; /*Twalk */
- char wname[IXP_MAX_WELEM][IXP_MAX_FLEN]; /*Twalk */
- unsigned short nwqid; /*Rwalk */
- Qid wqid[IXP_MAX_WELEM]; /*Rwalk */
- unsigned long long offset; /*Tread, Twrite */
- unsigned int count; /*Tread, Twrite, Rread */
- Stat stat; /*Rstat */
- unsigned short nstat; /*Twstat, Rstat */
- unsigned char data[IXP_MAX_MSG]; /*Twrite, Rread, Twstat,
- *Rstat */
-} Fcall;
-
-typedef struct IXPServer IXPServer;
-typedef struct IXPConn IXPConn;
-typedef struct IXPMap IXPMap;
-
-struct IXPMap {
- unsigned int fid;
- Qid qid;
-};
-
-struct IXPConn {
- int fd;
- void (*read) (IXPServer *, IXPConn *);
- void (*close) (IXPServer *, IXPConn *);
- IXPMap **map;
- size_t mapsz;
- Fcall *fcall;
- Fcall **pend;
- size_t pendsz;
-};
-
-struct IXPServer {
- int running;
- IXPConn **conn;
- size_t connsz;
- int maxfd;
- fd_set rd;
-};
-
-typedef struct {
- int fd;
- unsigned int root_fid;
- Qid root_qid;
- Fcall fcall;
- char *errstr;
-} IXPClient;
-
-/* client.c */
-int ixp_client_init(IXPClient *c, char *address);
-void ixp_client_deinit(IXPClient *c);
-int ixp_client_remove(IXPClient *c, unsigned int newfid, char *filepath);
-int ixp_client_create(IXPClient *c, unsigned int dirfid, char *name,
- unsigned int perm, unsigned char mode);
-int ixp_client_walk(IXPClient *c, unsigned int newfid, char *filepath);
-int ixp_client_open(IXPClient *c, unsigned int newfid, char *filepath,
- unsigned char mode);
-int ixp_client_read(IXPClient *c, unsigned int fid,
- unsigned long long offset, void *result,
- unsigned int res_len);
-int ixp_client_write(IXPClient *c, unsigned int fid,
- unsigned long long offset,
- unsigned int count, unsigned char *data);
-int ixp_client_close(IXPClient *c, unsigned int fid);
-
-/* convert.c */
-void *ixp_enc_u8(unsigned char *msg, unsigned char val);
-void *ixp_dec_u8(unsigned char *msg, unsigned char *val);
-void *ixp_enc_u16(unsigned char *msg, unsigned short val);
-void *ixp_dec_u16(unsigned char *msg, unsigned short *val);
-void *ixp_enc_u32(unsigned char *msg, unsigned int val);
-void *ixp_dec_u32(unsigned char *msg, unsigned int *val);
-void *ixp_enc_u64(unsigned char *msg, unsigned long long val);
-void *ixp_dec_u64(unsigned char *msg, unsigned long long *val);
-void *ixp_enc_string(unsigned char *msg, const char *s);
-void *ixp_dec_string(unsigned char *msg, char *string,
- unsigned short stringlen, unsigned short *len);
-void *ixp_enc_data(unsigned char *msg, unsigned char *data,
- unsigned int datalen);
-void *ixp_dec_data(unsigned char *msg, unsigned char *data,
- unsigned int datalen);
-void *ixp_enc_prefix(unsigned char *msg, unsigned int size,
- unsigned char id, unsigned short tag);
-void *ixp_dec_prefix(unsigned char *msg, unsigned int *size,
- unsigned char *id, unsigned short *tag);
-void *ixp_enc_qid(unsigned char *msg, Qid *qid);
-void *ixp_dec_qid(unsigned char *msg, Qid *qid);
-void *ixp_enc_stat(unsigned char *msg, Stat *stat);
-void *ixp_dec_stat(unsigned char *msg, Stat *stat);
-
-/* message.c */
-unsigned short ixp_sizeof_stat(Stat *stat);
-unsigned int ixp_fcall_to_msg(Fcall *fcall, void *msg, unsigned int msglen);
-unsigned int ixp_msg_to_fcall(void *msg, unsigned int msglen, Fcall *fcall);
-
-/* server.c */
-char *ixp_server_loop(IXPServer *s);
-IXPMap *ixp_server_fid2map(IXPConn *c, unsigned int fid);
-
-/* socket.c */
-int ixp_connect_sock(char *address);
-int ixp_accept_sock(int fd);
-int ixp_create_sock(char *address, char **errstr);
-
-/* transport.c */
-unsigned int ixp_send_message(int fd, void *msg, unsigned int msize, char **errstr);
-unsigned int ixp_recv_message(int fd, void *msg, unsigned int msglen, char **errstr);
diff --git a/libixp2/message.c b/libixp2/message.c
@@ -1,317 +0,0 @@
-/*
- * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "ixp.h"
-
-#define IXP_QIDSZ (sizeof(unsigned char) + sizeof(unsigned int)\
- + sizeof(unsigned long long))
-
-static unsigned short
-sizeof_string(const char *s)
-{
- return sizeof(unsigned short) + strlen(s);
-}
-
-unsigned short
-ixp_sizeof_stat(Stat * stat)
-{
- return IXP_QIDSZ
- + 2 * sizeof(unsigned short)
- + 4 * sizeof(unsigned int)
- + sizeof(unsigned long long)
- + sizeof_string(stat->name)
- + sizeof_string(stat->uid)
- + sizeof_string(stat->gid)
- + sizeof_string(stat->muid);
-}
-
-unsigned int
-ixp_fcall_to_msg(Fcall * fcall, void *msg, unsigned int msglen)
-{
- unsigned int i, msize =
- sizeof(unsigned char) + sizeof(unsigned short) +
- sizeof(unsigned int);
- void *p = msg;
-
- switch (fcall->id) {
- case TVERSION:
- case RVERSION:
- msize += sizeof(unsigned int) + sizeof_string(fcall->version);
- break;
- case TAUTH:
- msize +=
- sizeof(unsigned int) + sizeof_string(fcall->uname) +
- sizeof_string(fcall->aname);
- break;
- case RAUTH:
- case RATTACH:
- msize += IXP_QIDSZ;
- break;
- case TATTACH:
- msize +=
- 2 * sizeof(unsigned int) + sizeof_string(fcall->uname) +
- sizeof_string(fcall->aname);
- break;
- case RERROR:
- msize += sizeof_string(fcall->errstr);
- break;
- case RWRITE:
- case TCLUNK:
- case TREMOVE:
- case TSTAT:
- msize += sizeof(unsigned int);
- break;
- case TWALK:
- msize += sizeof(unsigned short) + 2 * sizeof(unsigned int);
- for(i = 0; i < fcall->nwname; i++)
- msize += sizeof_string(fcall->wname[i]);
- break;
- case TFLUSH:
- msize += sizeof(unsigned short);
- break;
- case RWALK:
- msize += sizeof(unsigned short) + fcall->nwqid * IXP_QIDSZ;
- break;
- case TOPEN:
- msize += sizeof(unsigned int) + sizeof(unsigned char);
- break;
- case ROPEN:
- case RCREATE:
- msize += IXP_QIDSZ + sizeof(unsigned int);
- break;
- case TCREATE:
- msize +=
- sizeof(unsigned char) + 2 * sizeof(unsigned int) +
- sizeof_string(fcall->name);
- break;
- case TREAD:
- msize += 2 * sizeof(unsigned int) + sizeof(unsigned long long);
- break;
- case RREAD:
- msize += sizeof(unsigned int) + fcall->count;
- break;
- case TWRITE:
- msize +=
- 2 * sizeof(unsigned int) + sizeof(unsigned long long) +
- fcall->count;
- break;
- case RSTAT:
- msize += sizeof(unsigned short) + ixp_sizeof_stat(&fcall->stat);
- break;
- case TWSTAT:
- msize += sizeof(unsigned int) + sizeof(unsigned short) + ixp_sizeof_stat(&fcall->stat);
- break;
- default:
- break;
- }
-
- if(msize > msglen)
- return 0;
- p = ixp_enc_prefix(p, msize, fcall->id, fcall->tag);
-
- switch (fcall->id) {
- case TVERSION:
- case RVERSION:
- p = ixp_enc_u32(p, fcall->maxmsg);
- p = ixp_enc_string(p, fcall->version);
- break;
- case TAUTH:
- p = ixp_enc_u32(p, fcall->afid);
- p = ixp_enc_string(p, fcall->uname);
- p = ixp_enc_string(p, fcall->aname);
- break;
- case RAUTH:
- p = ixp_enc_qid(p, &fcall->aqid);
- break;
- case RATTACH:
- p = ixp_enc_qid(p, &fcall->qid);
- break;
- case TATTACH:
- p = ixp_enc_u32(p, fcall->fid);
- p = ixp_enc_u32(p, fcall->afid);
- p = ixp_enc_string(p, fcall->uname);
- p = ixp_enc_string(p, fcall->aname);
- break;
- case RERROR:
- p = ixp_enc_string(p, fcall->errstr);
- break;
- case TFLUSH:
- p = ixp_enc_u16(p, fcall->oldtag);
- break;
- case TWALK:
- p = ixp_enc_u32(p, fcall->fid);
- p = ixp_enc_u32(p, fcall->newfid);
- p = ixp_enc_u16(p, fcall->nwname);
- for(i = 0; i < fcall->nwname; i++)
- p = ixp_enc_string(p, fcall->wname[i]);
- break;
- case RWALK:
- p = ixp_enc_u16(p, fcall->nwqid);
- for(i = 0; i < fcall->nwqid; i++)
- p = ixp_enc_qid(p, &fcall->wqid[i]);
- break;
- case TOPEN:
- p = ixp_enc_u32(p, fcall->fid);
- p = ixp_enc_u8(p, fcall->mode);
- break;
- case ROPEN:
- case RCREATE:
- p = ixp_enc_qid(p, &fcall->qid);
- p = ixp_enc_u32(p, fcall->iounit);
- break;
- case TCREATE:
- p = ixp_enc_u32(p, fcall->fid);
- p = ixp_enc_string(p, fcall->name);
- p = ixp_enc_u32(p, fcall->perm);
- p = ixp_enc_u8(p, fcall->mode);
- break;
- case TREAD:
- p = ixp_enc_u32(p, fcall->fid);
- p = ixp_enc_u64(p, fcall->offset);
- p = ixp_enc_u32(p, fcall->count);
- break;
- case RREAD:
- p = ixp_enc_u32(p, fcall->count);
- p = ixp_enc_data(p, fcall->data, fcall->count);
- break;
- case TWRITE:
- p = ixp_enc_u32(p, fcall->fid);
- p = ixp_enc_u64(p, fcall->offset);
- p = ixp_enc_u32(p, fcall->count);
- p = ixp_enc_data(p, fcall->data, fcall->count);
- break;
- case RWRITE:
- p = ixp_enc_u32(p, fcall->count);
- break;
- case TCLUNK:
- case TREMOVE:
- case TSTAT:
- p = ixp_enc_u32(p, fcall->fid);
- break;
- case RSTAT:
- p = ixp_enc_u16(p, ixp_sizeof_stat(&fcall->stat));
- p = ixp_enc_stat(p, &fcall->stat);
- break;
- case TWSTAT:
- p = ixp_enc_u32(p, fcall->fid);
- p = ixp_enc_u16(p, ixp_sizeof_stat(&fcall->stat));
- p = ixp_enc_stat(p, &fcall->stat);
- break;
- }
-
- if(msg + msize == p)
- return msize;
- return 0;
-}
-
-unsigned int
-ixp_msg_to_fcall(void *msg, unsigned int msglen, Fcall * fcall)
-{
- unsigned int i, msize;
- unsigned short len;
- void *p = ixp_dec_prefix(msg, &msize, &fcall->id, &fcall->tag);
-
- if(msize > msglen) /* bad message */
- return 0;
-
- switch (fcall->id) {
- case TVERSION:
- case RVERSION:
- p = ixp_dec_u32(p, &fcall->maxmsg);
- p = ixp_dec_string(p, fcall->version, sizeof(fcall->version), &len);
- break;
- case TAUTH:
- p = ixp_dec_u32(p, &fcall->afid);
- p = ixp_dec_string(p, fcall->uname, sizeof(fcall->uname), &len);
- p = ixp_dec_string(p, fcall->aname, sizeof(fcall->aname), &len);
- break;
- case RAUTH:
- p = ixp_dec_qid(p, &fcall->aqid);
- break;
- case RATTACH:
- p = ixp_dec_qid(p, &fcall->qid);
- break;
- case TATTACH:
- p = ixp_dec_u32(p, &fcall->fid);
- p = ixp_dec_u32(p, &fcall->afid);
- p = ixp_dec_string(p, fcall->uname, sizeof(fcall->uname), &len);
- p = ixp_dec_string(p, fcall->aname, sizeof(fcall->aname), &len);
- break;
- case RERROR:
- p = ixp_dec_string(p, fcall->errstr, sizeof(fcall->errstr), &len);
- break;
- case TFLUSH:
- p = ixp_dec_u16(p, &fcall->oldtag);
- break;
- case TWALK:
- p = ixp_dec_u32(p, &fcall->fid);
- p = ixp_dec_u32(p, &fcall->newfid);
- p = ixp_dec_u16(p, &fcall->nwname);
- for(i = 0; i < fcall->nwname; i++) {
-
- p = ixp_dec_string(p, fcall->wname[i], IXP_MAX_FLEN, &len);
- }
- break;
- case RWALK:
- p = ixp_dec_u16(p, &fcall->nwqid);
- for(i = 0; i < fcall->nwqid; i++)
- p = ixp_dec_qid(p, &fcall->wqid[i]);
- break;
- case TOPEN:
- p = ixp_dec_u32(p, &fcall->fid);
- p = ixp_dec_u8(p, &fcall->mode);
- break;
- case ROPEN:
- case RCREATE:
- p = ixp_dec_qid(p, &fcall->qid);
- p = ixp_dec_u32(p, &fcall->iounit);
- break;
- case TCREATE:
- p = ixp_dec_u32(p, &fcall->fid);
- p = ixp_dec_string(p, fcall->name, sizeof(fcall->name), &len);
- p = ixp_dec_u32(p, &fcall->perm);
- p = ixp_dec_u8(p, &fcall->mode);
- break;
- case TREAD:
- p = ixp_dec_u32(p, &fcall->fid);
- p = ixp_dec_u64(p, &fcall->offset);
- p = ixp_dec_u32(p, &fcall->count);
- break;
- case RREAD:
- p = ixp_dec_u32(p, &fcall->count);
- p = ixp_dec_data(p, fcall->data, fcall->count);
- break;
- case TWRITE:
- p = ixp_dec_u32(p, &fcall->fid);
- p = ixp_dec_u64(p, &fcall->offset);
- p = ixp_dec_u32(p, &fcall->count);
- p = ixp_dec_data(p, fcall->data, fcall->count);
- break;
- case RWRITE:
- p = ixp_dec_u32(p, &fcall->count);
- break;
- case TCLUNK:
- case TREMOVE:
- case TSTAT:
- p = ixp_dec_u32(p, &fcall->fid);
- break;
- case RSTAT:
- p = ixp_dec_u16(p, &len);
- p = ixp_dec_stat(p, &fcall->stat);
- break;
- case TWSTAT:
- p = ixp_dec_u32(p, &fcall->fid);
- p = ixp_dec_u16(p, &len);
- p = ixp_dec_stat(p, &fcall->stat);
- break;
- }
-
- if(msg + msize == p)
- return msize;
- return 0;
-}
diff --git a/libixp2/server.c b/libixp2/server.c
@@ -1,73 +0,0 @@
-/*
- * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include "ixp.h"
-#include "cext.h"
-
-static void
-prepare_select(IXPServer *s)
-{
- int i;
- FD_ZERO(&s->rd);
- for(i = 0; (i < s->connsz) && s->conn[i]; i++) {
- if(s->maxfd < s->conn[i]->fd)
- s->maxfd = s->conn[i]->fd;
- if(s->conn[i]->read)
- FD_SET(s->conn[i]->fd, &s->rd);
- }
-}
-
-static void
-handle_conns(IXPServer *s)
-{
- int i;
- for(i = 0; (i < s->connsz) && s->conn[i]; i++)
- if(FD_ISSET(s->conn[i]->fd, &s->rd) && s->conn[i]->read)
- /* call read handler */
- s->conn[i]->read(s, s->conn[i]);
-}
-
-char *
-ixp_server_loop(IXPServer *s)
-{
- int r;
- s->running = 1;
-
- /* main loop */
- while(s->running && s->conn) {
-
- prepare_select(s);
-
- r = select(s->maxfd + 1, &s->rd, 0, 0, 0);
- if(r == -1 && errno == EINTR)
- continue;
- if(r < 0)
- return "fatal select error";
- else if(r > 0)
- handle_conns(s);
- }
- return nil;
-}
-
-IXPMap *
-ixp_server_fid2map(IXPConn *c, unsigned int fid)
-{
- size_t i;
- for(i = 0; (i < c->mapsz) && c->map[i]; i++)
- if(c->map[i]->fid == fid)
- return c->map[i];
- return nil;
-}
diff --git a/libixp2/socket.c b/libixp2/socket.c
@@ -1,204 +0,0 @@
-/*
- * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include "cext.h"
-#include "ixp.h"
-
-static int
-connect_unix_sock(char *address)
-{
- int fd = 0;
- struct sockaddr_un addr = { 0 };
- socklen_t su_len;
-
- /* init */
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, address, sizeof(addr.sun_path));
- su_len = sizeof(struct sockaddr) + strlen(addr.sun_path);
-
- if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
- return -1;
- if(connect(fd, (struct sockaddr *) &addr, su_len)) {
- close(fd);
- return -1;
- }
- return fd;
-}
-
-static int
-connect_inet_sock(char *host)
-{
- int fd = 0;
- struct sockaddr_in addr = { 0 };
- struct hostent *hp;
- char *port = strrchr(host, '!');
- const char *errstr = nil;
- unsigned int prt;
-
- *port = 0;
- port++;
- prt = cext_strtonum(port, 1024, 65535, &errstr);
- if(errstr)
- return -1;
-
- /* init */
- if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
- return -1;
- hp = gethostbyname(host);
- addr.sin_family = AF_INET;
- addr.sin_port = htons(prt);
- bcopy(hp->h_addr, &addr.sin_addr, hp->h_length);
-
- if(connect(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in))) {
- close(fd);
- return -1;
- }
- return fd;
-}
-
-int
-ixp_connect_sock(char *address)
-{
- char *p = strchr(address, '!');
- char *addr, *type;
-
- if(!p)
- return -1;
- *p = 0;
-
- addr = &p[1];
- type = address; /* unix, inet */
-
- if(!strncmp(type, "unix", 5))
- return connect_unix_sock(addr);
- else if(!strncmp(type, "tcp", 4))
- return connect_inet_sock(addr);
- return -1;
-}
-
-int
-ixp_accept_sock(int fd)
-{
- socklen_t su_len;
- struct sockaddr_un addr = { 0 };
-
- su_len = sizeof(struct sockaddr);
- return accept(fd, (struct sockaddr *) &addr, &su_len);
-}
-
-static int
-create_inet_sock(char *host, char **errstr)
-{
- int fd;
- struct sockaddr_in addr = { 0 };
- char *port = strrchr(host, '!');
- unsigned int prt;
-
- if(!port) {
- *errstr = "no port provided in address";
- return -1;
- }
- *port = 0;
- port++;
- prt = cext_strtonum(port, 1024, 65535, (const char **)errstr);
- if(*errstr)
- return -1;
- signal(SIGPIPE, SIG_IGN);
- if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- *errstr = "cannot open socket";
- return -1;
- }
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = htonl(INADDR_ANY);
- addr.sin_port = htons(prt);
-
- if(bind(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) < 0) {
- *errstr = "cannot bind socket";
- close(fd);
- return -1;
- }
-
- if(listen(fd, IXP_MAX_CACHE) < 0) {
- *errstr = "cannot listen on socket";
- close(fd);
- return -1;
- }
- return fd;
-}
-
-static int
-create_unix_sock(char *file, char **errstr)
-{
- int fd;
- int yes = 1;
- struct sockaddr_un addr = { 0 };
- socklen_t su_len;
-
- signal(SIGPIPE, SIG_IGN);
- if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
- *errstr = "cannot open socket";
- return -1;
- }
- if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
- (char *) &yes, sizeof(yes)) < 0) {
- *errstr = "cannot set socket options";
- close(fd);
- return -1;
- }
- addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, file, sizeof(addr.sun_path));
- su_len = sizeof(struct sockaddr) + strlen(addr.sun_path);
-
- unlink(file); /* remove old socket, if any */
- if(bind(fd, (struct sockaddr *) &addr, su_len) < 0) {
- *errstr = "cannot bind socket";
- close(fd);
- return -1;
- }
- chmod(file, S_IRWXU);
-
- if(listen(fd, IXP_MAX_CACHE) < 0) {
- *errstr = "cannot listen on socket";
- close(fd);
- return -1;
- }
- return fd;
-}
-
-int
-ixp_create_sock(char *address, char **errstr)
-{
- char *p = strchr(address, '!');
- char *addr, *type;
-
- if(!p) {
- *errstr = "no socket type defined";
- return -1;
- }
- *p = 0;
-
- addr = &p[1];
- type = address; /* unix, inet */
-
- if(!strncmp(type, "unix", 5))
- return create_unix_sock(addr, errstr);
- else if(!strncmp(type, "tcp", 4))
- return create_inet_sock(addr, errstr);
- else
- *errstr = "unkown socket type";
- return -1;
-}
diff --git a/libixp2/transport.c b/libixp2/transport.c
@@ -1,81 +0,0 @@
-/*
- * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-
-#include <errno.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <unistd.h>
-
-#include "ixp.h"
-
-#include <cext.h>
-
-unsigned int
-ixp_send_message(int fd, void *msg, unsigned int msize, char **errstr)
-{
- unsigned int num = 0;
- int r;
-
- /* send message */
- while(num < msize) {
- r = write(fd, msg + num, msize - num);
- if(r == -1 && errno == EINTR)
- continue;
- if(r < 1) {
- *errstr = "cannot send message";
- return 0;
- }
- num += r;
- }
- return num;
-}
-
-static unsigned int
-ixp_recv_data(int fd, void *msg, unsigned int msize, char **errstr)
-{
- unsigned int num = 0;
- int r = 0;
-
- /* receive data */
- while(num < msize) {
- r = read(fd, msg + num, msize - num);
- if(r == -1 && errno == EINTR)
- continue;
- if(r < 1) {
- *errstr = "cannot receive data";
- return 0;
- }
- num += r;
- }
- return num;
-}
-
-unsigned int
-ixp_recv_message(int fd, void *msg, unsigned int msglen, char **errstr)
-{
- unsigned int msize;
-
- /* receive header */
- if(ixp_recv_data(fd, msg, sizeof(unsigned int), errstr) !=
- sizeof(unsigned int))
- return 0;
- ixp_dec_u32(msg, &msize);
- if(msize > msglen) {
- *errstr = "message size exceeds buffer size";
- return 0;
- }
- /* receive message */
- if(ixp_recv_data
- (fd, msg + sizeof(unsigned int), msize - sizeof(unsigned int),
- errstr)
- != msize - sizeof(unsigned int))
- return 0;
- return msize;
-}
diff --git a/libwmii/Makefile b/libwmii/Makefile
@@ -6,7 +6,7 @@ include ../config.mk
CFLAGS += -I../liblitz -I../libixp -I../libcext
LDFLAGS += -L../liblitz -llitz -L../libixp -lixp -L../libcext -lcext
-SRC = ixputil.c spawn.c wm.c
+SRC = spawn.c wm.c
OBJ = ${SRC:.c=.o}
diff --git a/libwmii/ixputil.c b/libwmii/ixputil.c
@@ -1,98 +0,0 @@
-/*
- * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
- * See LICENSE file for license details.
- */
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "wmii.h"
-
-static pid_t mypid;
-static char *mysockfile;
-
-File *
-wmii_create_ixpfile(IXPServer * s, char *key, char *val)
-{
- File *f = ixp_create(s, key);
- if(f && !is_directory(f)) {
- size_t l = val ? strlen(val) : 0;
- f->content = l ? strdup(val) : 0;
- f->size = l;
- return f;
- }
- /* forbidden, file is directory */
- return 0;
-}
-
-void
-wmii_get_ixppath(File * f, char *path, size_t size)
-{
- char buf[512];
-
- buf[0] = 0;
- if(path)
- cext_strlcpy(buf, path, sizeof(buf));
- snprintf(path, size, "%s/", f->name);
- if(buf[0] != 0)
- cext_strlcat(path, buf, size);
- if(f->parent)
- wmii_get_ixppath(f->parent, path, size);
-}
-
-void
-wmii_move_ixpfile(File * f, File * to_parent)
-{
- File *p = f->parent;
- File *fil = p->content;
-
- /* detach */
- if(p->content == f)
- p->content = fil->next;
- else {
- while(fil->next != f)
- fil = fil->next;
- fil->next = f->next;
- }
- f->next = 0;
-
-
- /* attach */
- if(!to_parent->content)
- to_parent->content = f;
- else {
- for(fil = to_parent->content; fil->next; fil = fil->next);
- fil->next = f;
- }
- f->parent = to_parent;
-}
-
-static void
-exit_cleanup()
-{
- if(mypid == getpid())
- unlink(mysockfile);
-}
-
-IXPServer *
-wmii_setup_server(char *sockfile)
-{
- IXPServer *s;
-
- if(!sockfile) {
- fprintf(stderr, "%s\n", "libwmii: no socket file provided");
- exit(1);
- }
- mysockfile = sockfile;
- mypid = getpid();
- s = init_server(sockfile, exit_cleanup);
- if(!s) {
- perror("libwmii: cannot initialize IXP server");
- exit(1);
- }
- return s;
-}
diff --git a/libwmii/wmii.h b/libwmii/wmii.h
@@ -16,12 +16,6 @@ struct Action {
void (*func) (void *obj, char *);
};
-/* ixputil.c */
-File *wmii_create_ixpfile(IXPServer * s, char *key, char *val);
-void wmii_get_ixppath(File * f, char *path, size_t size);
-void wmii_move_ixpfile(File * f, File * to_parent);
-IXPServer *wmii_setup_server(char *sockfile);
-
/* spawn.c */
void wmii_spawn(void *dpy, char *cmd);