Initial, non-functional code drop.
This commit is contained in:
parent
be76f4b73e
commit
f46d2136e9
13 changed files with 1699 additions and 0 deletions
7
Makefile
Normal file
7
Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
LIB= 9p
|
||||
SHLIB_MAJOR= 1
|
||||
SRCS= lib9p.c connection.c request.c log.c transport/socket.c backend/fs.c
|
||||
INCS= lib9p.h fcall.h log.h backend/fs.h
|
||||
CFLAGS= -g -O0
|
||||
|
||||
.include <bsd.lib.mk>
|
173
backend/fs.c
Normal file
173
backend/fs.c
Normal file
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Based on libixp code: ©2007-2010 Kris Maglione <maglione.k at Gmail>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include "../lib9p.h"
|
||||
|
||||
static void fs_attach(void *, struct l9p_request *);
|
||||
static void fs_clunk(void *, struct l9p_request *);
|
||||
static void fs_create(void *, struct l9p_request *);
|
||||
static void fs_flush(void *, struct l9p_request *);
|
||||
static void fs_open(void *, struct l9p_request *);
|
||||
static void fs_read(void *, struct l9p_request *);
|
||||
static void fs_remove(void *, struct l9p_request *);
|
||||
static void fs_stat(void *, struct l9p_request *);
|
||||
static void fs_walk(void *, struct l9p_request *);
|
||||
static void fs_write(void *, struct l9p_request *);
|
||||
static void fs_wstat(void *, struct l9p_request *);
|
||||
|
||||
struct fs_softc
|
||||
{
|
||||
const char *fs_rootpath;
|
||||
};
|
||||
|
||||
struct openfile
|
||||
{
|
||||
DIR *dir;
|
||||
int fd;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static struct openfile *
|
||||
open_fid(const char *path)
|
||||
{
|
||||
struct openfile *ret;
|
||||
|
||||
ret = malloc(sizeof(*ret));
|
||||
ret->fd = -1;
|
||||
ret->name = strdup(path);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static void
|
||||
fs_attach(void *softc, struct l9p_request *req)
|
||||
{
|
||||
struct fs_softc *sc = (struct fs_softc *)softc;
|
||||
|
||||
req->lr_fid->lo_qid.type = L9P_QTDIR;
|
||||
req->lr_fid->lo_qid.path = (uintptr_t)req->lr_fid;
|
||||
req->lr_fid->lo_aux = open_fid(sc->fs_rootpath);
|
||||
req->lr_resp.rattach.qid = req->lr_fid->lo_qid;
|
||||
|
||||
l9p_respond(req, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
fs_clunk(void *softc, struct l9p_request *req)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
fs_create(void *softc, struct l9p_request *req)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
fs_flush(void *softc, struct l9p_request *req)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
fs_open(void *softc, struct l9p_request *req)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
fs_read(void *softc, struct l9p_request *req)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
fs_remove(void *softc, struct l9p_request *req)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
fs_stat(void *softc, struct l9p_request *req)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
fs_walk(void *softc, struct l9p_request *req)
|
||||
{
|
||||
int i;
|
||||
char *name;
|
||||
|
||||
for (i = 0; i < req->lr_req.twalk.nwname; i++) {
|
||||
strcat(name, "/");
|
||||
strcat(name, req->lr_req.twalk.wname[i]);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
fs_write(void *softc, struct l9p_request *req)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
fs_wstat(void *softc, struct l9p_request *req)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
l9p_backend_fs_init(struct l9p_backend **backendp, const char *root)
|
||||
{
|
||||
struct l9p_backend *backend;
|
||||
|
||||
backend = malloc(sizeof(*backend));
|
||||
backend->attach = fs_attach;
|
||||
backend->clunk = fs_clunk;
|
||||
backend->create = fs_create;
|
||||
backend->flush = fs_flush;
|
||||
backend->open = fs_open;
|
||||
backend->read = fs_read;
|
||||
backend->remove = fs_remove;
|
||||
backend->stat = fs_stat;
|
||||
backend->walk = fs_walk;
|
||||
backend->write = fs_write;
|
||||
backend->wstat = fs_wstat;
|
||||
|
||||
*backendp = backend;
|
||||
return (0);
|
||||
}
|
31
backend/fs.h
Normal file
31
backend/fs.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../lib9p.h"
|
||||
|
||||
int l9p_backend_fs_init(struct l9p_backend **, const char *);
|
||||
|
122
connection.c
Normal file
122
connection.c
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/queue.h>
|
||||
#include "lib9p.h"
|
||||
|
||||
int
|
||||
l9p_server_init(struct l9p_server **serverp, struct l9p_backend *backend)
|
||||
{
|
||||
struct l9p_server *server;
|
||||
|
||||
server = malloc(sizeof(*server));
|
||||
server->ls_backend = backend;
|
||||
LIST_INIT(&server->ls_conns);
|
||||
|
||||
*serverp = server;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
l9p_connection_init(struct l9p_server *server, struct l9p_connection **conn)
|
||||
{
|
||||
struct l9p_connection *newconn;
|
||||
|
||||
newconn = malloc(sizeof(*newconn));
|
||||
LIST_INSERT_HEAD(&server->ls_conns, newconn, lc_link);
|
||||
*conn = newconn;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
l9p_connection_free(struct l9p_connection *conn)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
l9p_connection_on_send_request(struct l9p_connection *conn,
|
||||
void (*cb)(void *, size_t, void *), void *softc)
|
||||
{
|
||||
|
||||
conn->lc_send_request = cb;
|
||||
conn->lc_send_request_aux = softc;
|
||||
}
|
||||
|
||||
void
|
||||
l9p_connection_recv(struct l9p_connection *conn, void *buf, size_t len)
|
||||
{
|
||||
struct l9p_message msg;
|
||||
struct l9p_request *req;
|
||||
|
||||
req = malloc(sizeof(struct l9p_request));
|
||||
req->lr_conn = conn;
|
||||
msg.lm_buffer = buf;
|
||||
msg.lm_pos = buf;
|
||||
msg.lm_end = buf + len;
|
||||
msg.lm_mode = L9P_UNPACK;
|
||||
|
||||
if (l9p_pufcall(&msg, &req->lr_req) != 0) {
|
||||
|
||||
}
|
||||
|
||||
l9p_dispatch_request(req);
|
||||
}
|
||||
|
||||
void
|
||||
l9p_connection_close(struct l9p_connection *conn)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
struct l9p_openfile *
|
||||
l9p_connection_find_fid(struct l9p_connection *conn, uint32_t fid)
|
||||
{
|
||||
struct l9p_openfile *i;
|
||||
|
||||
LIST_FOREACH(i, &conn->lc_files, lo_link) {
|
||||
if (i->lo_fid == fid)
|
||||
return (i);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
struct l9p_request *
|
||||
l9p_connection_find_tag(struct l9p_connection *conn, uint32_t tag)
|
||||
{
|
||||
struct l9p_request *i;
|
||||
|
||||
LIST_FOREACH(i, &conn->lc_requests, lr_link) {
|
||||
if (i->lr_tag == tag)
|
||||
return (i);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
48
example/server.c
Normal file
48
example/server.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <err.h>
|
||||
#include "../lib9p.h"
|
||||
#include "../transport/socket.h"
|
||||
#include "../backend/fs.h"
|
||||
|
||||
int
|
||||
main(int argc, const char *argv[])
|
||||
{
|
||||
struct l9p_backend *fs_backend;
|
||||
struct l9p_server *server;
|
||||
|
||||
if (l9p_backend_fs_init(&fs_backend, argv[1]) != 0)
|
||||
errx(1, "Cannot init backend:");
|
||||
|
||||
if (l9p_server_init(&server, fs_backend) != 0)
|
||||
errx(1, "Cannot create server:");
|
||||
|
||||
l9p_start_server(server, "0.0.0.0", "564");
|
||||
}
|
214
fcall.h
Normal file
214
fcall.h
Normal file
|
@ -0,0 +1,214 @@
|
|||
/*
|
||||
* Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Based on libixp code: ©2007-2010 Kris Maglione <maglione.k at Gmail>
|
||||
*/
|
||||
|
||||
#ifndef LIB9P_FCALL_H
|
||||
#define LIB9P_FCALL_H
|
||||
|
||||
#define L9P_MAX_WELEM 256
|
||||
|
||||
enum l9p_ftype {
|
||||
L9P_TVERSION = 100,
|
||||
L9P_RVERSION,
|
||||
L9P_TAUTH = 102,
|
||||
L9P_RAUTH,
|
||||
L9P_TATTACH = 104,
|
||||
L9P_RATTACH,
|
||||
L9P_TERROR = 106, /* illegal */
|
||||
L9P_RERROR,
|
||||
L9P_TFLUSH = 108,
|
||||
L9P_RFLUSH,
|
||||
L9P_TWALK = 110,
|
||||
L9P_RWALK,
|
||||
L9P_TOPEN = 112,
|
||||
L9P_ROPEN,
|
||||
L9P_TCREATE = 114,
|
||||
L9P_RCREATE,
|
||||
L9P_TREAD = 116,
|
||||
L9P_RREAD,
|
||||
L9P_TWRITE = 118,
|
||||
L9P_RWRITE,
|
||||
L9P_TCLUNK = 120,
|
||||
L9P_RCLUNK,
|
||||
L9P_TREMOVE = 122,
|
||||
L9P_RREMOVE,
|
||||
L9P_TSTAT = 124,
|
||||
L9P_RSTAT,
|
||||
L9P_TWSTAT = 126,
|
||||
L9P_RWSTAT,
|
||||
};
|
||||
|
||||
enum l9p_qid_type
|
||||
{
|
||||
L9P_QTDIR = 0x80, /* type bit for directories */
|
||||
L9P_QTAPPEND = 0x40, /* type bit for append only files */
|
||||
L9P_QTEXCL = 0x20, /* type bit for exclusive use files */
|
||||
L9P_QTMOUNT = 0x10, /* type bit for mounted channel */
|
||||
L9P_QTAUTH = 0x08, /* type bit for authentication file */
|
||||
L9P_QTTMP = 0x04, /* type bit for non-backed-up file */
|
||||
L9P_QTSYMLINK = 0x02,/* type bit for symbolic link */
|
||||
L9P_QTFILE = 0x00 /* type bits for plain file */
|
||||
};
|
||||
|
||||
struct l9p_hdr
|
||||
{
|
||||
uint8_t type;
|
||||
uint16_t tag;
|
||||
uint32_t fid;
|
||||
};
|
||||
|
||||
struct l9p_qid
|
||||
{
|
||||
enum l9p_qid_type type;
|
||||
uint32_t version;
|
||||
uint64_t path;
|
||||
};
|
||||
|
||||
struct l9p_stat
|
||||
{
|
||||
uint16_t type;
|
||||
uint32_t dev;
|
||||
struct l9p_qid qid;
|
||||
uint32_t mode;
|
||||
uint32_t atime;
|
||||
uint32_t mtime;
|
||||
uint64_t length;
|
||||
char *name;
|
||||
char *uid;
|
||||
char *gid;
|
||||
char *muid;
|
||||
};
|
||||
|
||||
struct l9p_f_version
|
||||
{
|
||||
struct l9p_hdr hdr;
|
||||
uint32_t msize;
|
||||
char *version;
|
||||
};
|
||||
|
||||
struct l9p_f_tflush
|
||||
{
|
||||
struct l9p_hdr hdr;
|
||||
uint16_t oldtag;
|
||||
};
|
||||
|
||||
struct l9p_f_error
|
||||
{
|
||||
struct l9p_hdr hdr;
|
||||
char *ename;
|
||||
};
|
||||
|
||||
struct l9p_f_ropen
|
||||
{
|
||||
struct l9p_hdr hdr;
|
||||
struct l9p_qid qid;
|
||||
uint32_t iounit;
|
||||
};
|
||||
|
||||
struct l9p_f_rauth
|
||||
{
|
||||
struct l9p_hdr hdr;
|
||||
struct l9p_qid aqid;
|
||||
};
|
||||
|
||||
struct l9p_f_attach
|
||||
{
|
||||
struct l9p_hdr hdr;
|
||||
uint32_t afid;
|
||||
char *uname;
|
||||
char *aname;
|
||||
};
|
||||
|
||||
struct l9p_f_tcreate
|
||||
{
|
||||
struct l9p_hdr hdr;
|
||||
uint32_t perm;
|
||||
char *name;
|
||||
uint8_t mode; /* +Topen */
|
||||
};
|
||||
|
||||
struct l9p_f_twalk
|
||||
{
|
||||
struct l9p_hdr hdr;
|
||||
uint32_t newfid;
|
||||
uint16_t nwname;
|
||||
char *wname[L9P_MAX_WELEM];
|
||||
};
|
||||
|
||||
struct l9p_f_rwalk
|
||||
{
|
||||
struct l9p_hdr hdr;
|
||||
uint16_t nwqid;
|
||||
struct l9p_qid wqid[L9P_MAX_WELEM];
|
||||
};
|
||||
|
||||
struct l9p_f_io
|
||||
{
|
||||
struct l9p_hdr hdr;
|
||||
uint64_t offset; /* Tread, Twrite */
|
||||
uint32_t count; /* Tread, Twrite, Rread */
|
||||
char *data; /* Twrite, Rread */
|
||||
};
|
||||
|
||||
struct l9p_f_rstat
|
||||
{
|
||||
struct l9p_hdr hdr;
|
||||
uint16_t nstat;
|
||||
uint8_t *stat;
|
||||
};
|
||||
|
||||
struct l9p_f_twstat
|
||||
{
|
||||
struct l9p_hdr hdr;
|
||||
struct l9p_stat stat;
|
||||
};
|
||||
|
||||
union l9p_fcall
|
||||
{
|
||||
struct l9p_hdr hdr;
|
||||
struct l9p_f_version version;
|
||||
struct l9p_f_tflush tflush;
|
||||
struct l9p_f_ropen ropen;
|
||||
struct l9p_f_ropen rcreate;
|
||||
struct l9p_f_ropen rattach;
|
||||
struct l9p_f_error error;
|
||||
struct l9p_f_rauth rauth;
|
||||
struct l9p_f_attach tattach;
|
||||
struct l9p_f_attach tauth;
|
||||
struct l9p_f_tcreate tcreate;
|
||||
struct l9p_f_tcreate topen;
|
||||
struct l9p_f_twalk twalk;
|
||||
struct l9p_f_rwalk rwalk;
|
||||
struct l9p_f_twstat twstat;
|
||||
struct l9p_f_rstat rstat;
|
||||
struct l9p_f_io io;
|
||||
};
|
||||
|
||||
#endif //LIB9P_FCALL_H
|
366
lib9p.c
Normal file
366
lib9p.c
Normal file
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Based on libixp code: ©2007-2010 Kris Maglione <maglione.k at Gmail>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include "lib9p.h"
|
||||
|
||||
#define N(ary) (sizeof(ary) / sizeof(*ary))
|
||||
#define STRING_SIZE(s) (L9P_WORD + strlen(s))
|
||||
#define QID_SIZE (L9P_BYTE + L9P_DWORD + L9P_QWORD)
|
||||
|
||||
static void l9p_puint(struct l9p_message *, enum l9p_integer_type, uint32_t *);
|
||||
static inline void l9p_pu8(struct l9p_message *, uint8_t *);
|
||||
static inline void l9p_pu16(struct l9p_message *, uint16_t *);
|
||||
static inline void l9p_pu32(struct l9p_message *, uint32_t *);
|
||||
static inline void l9p_pu64(struct l9p_message *, uint64_t *);
|
||||
static void l9p_pustring(struct l9p_message *, char **s);
|
||||
static void l9p_pustrings(struct l9p_message *, uint16_t *,char *[], size_t);
|
||||
static void l9p_pudata(struct l9p_message *, uint8_t **, size_t);
|
||||
static void l9p_puqid(struct l9p_message *, struct l9p_qid *);
|
||||
static void l9p_puqids(struct l9p_message *, uint16_t *, struct l9p_qid *q,
|
||||
size_t);
|
||||
static void l9p_pustat(struct l9p_message *, struct l9p_stat *);
|
||||
static uint16_t l9p_sizeof_stat(struct l9p_stat *);
|
||||
|
||||
|
||||
static void
|
||||
l9p_puint(struct l9p_message *msg, enum l9p_integer_type size, uint32_t *val)
|
||||
{
|
||||
uint8_t *pos;
|
||||
int v;
|
||||
|
||||
if(msg->lm_pos + size <= msg->lm_end) {
|
||||
pos = (uint8_t*)msg->lm_pos;
|
||||
switch (msg->lm_mode) {
|
||||
case L9P_PACK:
|
||||
v = *val;
|
||||
switch (size) {
|
||||
case L9P_DWORD:
|
||||
pos[3] = v>>24;
|
||||
pos[2] = v>>16;
|
||||
case L9P_WORD:
|
||||
pos[1] = v>>8;
|
||||
case L9P_BYTE:
|
||||
pos[0] = v;
|
||||
break;
|
||||
}
|
||||
case L9P_UNPACK:
|
||||
v = 0;
|
||||
switch (size) {
|
||||
case L9P_DWORD:
|
||||
v |= pos[3]<<24;
|
||||
v |= pos[2]<<16;
|
||||
case L9P_WORD:
|
||||
v |= pos[1]<<8;
|
||||
case L9P_BYTE:
|
||||
v |= pos[0];
|
||||
break;
|
||||
}
|
||||
*val = v;
|
||||
}
|
||||
}
|
||||
msg->lm_pos += size;
|
||||
}
|
||||
|
||||
static inline void
|
||||
l9p_pu8(struct l9p_message *msg, uint8_t *val)
|
||||
{
|
||||
uint32_t v;
|
||||
|
||||
v = *val;
|
||||
l9p_puint(msg, L9P_BYTE, &v);
|
||||
*val = (uint8_t)v;
|
||||
}
|
||||
|
||||
static inline void
|
||||
l9p_pu16(struct l9p_message *msg, uint16_t *val)
|
||||
{
|
||||
uint32_t v;
|
||||
|
||||
v = *val;
|
||||
l9p_puint(msg, L9P_WORD, &v);
|
||||
*val = (uint16_t)v;
|
||||
}
|
||||
|
||||
static inline void
|
||||
l9p_pu32(struct l9p_message *msg, uint32_t *val)
|
||||
{
|
||||
l9p_puint(msg, L9P_DWORD, val);
|
||||
}
|
||||
|
||||
static inline void
|
||||
l9p_pu64(struct l9p_message *msg, uint64_t *val)
|
||||
{
|
||||
uint32_t vl, vb;
|
||||
|
||||
vl = (uint)*val;
|
||||
vb = (uint)(*val>>32);
|
||||
l9p_puint(msg, L9P_DWORD, &vl);
|
||||
l9p_puint(msg, L9P_DWORD, &vb);
|
||||
*val = vl | ((uint64_t)vb<<32);
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_pustring(struct l9p_message *msg, char **s)
|
||||
{
|
||||
uint16_t len;
|
||||
|
||||
if(msg->lm_mode == L9P_PACK)
|
||||
len = strlen(*s);
|
||||
l9p_pu16(msg, &len);
|
||||
|
||||
if (msg->lm_pos + len <= msg->lm_end) {
|
||||
if (msg->lm_mode == L9P_UNPACK) {
|
||||
*s = malloc(len + 1);
|
||||
memcpy(*s, msg->lm_pos, len);
|
||||
(*s)[len] = '\0';
|
||||
} else
|
||||
memcpy(msg->lm_pos, *s, len);
|
||||
}
|
||||
msg->lm_pos += len;
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_pustrings(struct l9p_message *msg, uint16_t *num, char *strings[],
|
||||
size_t max)
|
||||
{
|
||||
char *s;
|
||||
uint i, size;
|
||||
uint16_t len;
|
||||
|
||||
l9p_pu16(msg, num);
|
||||
if (*num > max) {
|
||||
msg->lm_pos = msg->lm_end+1;
|
||||
return;
|
||||
}
|
||||
|
||||
s = NULL;
|
||||
|
||||
if (msg->lm_mode == L9P_UNPACK) {
|
||||
s = msg->lm_pos;
|
||||
size = 0;
|
||||
for (i = 0; i < *num; i++) {
|
||||
l9p_pu16(msg, &len);
|
||||
msg->lm_pos += len;
|
||||
size += len;
|
||||
if (msg->lm_pos > msg->lm_end)
|
||||
return;
|
||||
}
|
||||
msg->lm_pos = s;
|
||||
size += *num;
|
||||
s = malloc(size);
|
||||
}
|
||||
|
||||
for (i = 0; i < *num; i++) {
|
||||
if (msg->lm_mode == L9P_PACK)
|
||||
len = strlen(strings[i]);
|
||||
l9p_pu16(msg, &len);
|
||||
|
||||
if (msg->lm_mode == L9P_UNPACK) {
|
||||
memcpy(s, msg->lm_pos, len);
|
||||
strings[i] = (char*)s;
|
||||
s += len;
|
||||
msg->lm_pos += len;
|
||||
*s++ = '\0';
|
||||
} else
|
||||
l9p_pudata(msg, &strings[i], len);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_pudata(struct l9p_message *msg, uint8_t **data, size_t len)
|
||||
{
|
||||
if (msg->lm_pos + len <= msg->lm_end) {
|
||||
if (msg->lm_mode == L9P_UNPACK) {
|
||||
*data = malloc(len);
|
||||
memcpy(*data, msg->lm_pos, len);
|
||||
} else
|
||||
memcpy(msg->lm_pos, *data, len);
|
||||
}
|
||||
msg->lm_pos += len;
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_puqid(struct l9p_message *msg, struct l9p_qid *qid)
|
||||
{
|
||||
l9p_pu8(msg, &qid->type);
|
||||
l9p_pu32(msg, &qid->version);
|
||||
l9p_pu64(msg, &qid->path);
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_puqids(struct l9p_message *msg, uint16_t *num, struct l9p_qid *qids,
|
||||
size_t max)
|
||||
{
|
||||
int i;
|
||||
l9p_pu16(msg, num);
|
||||
if (*num > max) {
|
||||
msg->lm_pos = msg->lm_end + 1;
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < *num; i++)
|
||||
l9p_puqid(msg, &qids[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_pustat(struct l9p_message *msg, struct l9p_stat *stat)
|
||||
{
|
||||
uint16_t size;
|
||||
|
||||
if(msg->lm_mode == L9P_PACK)
|
||||
size = l9p_sizeof_stat(stat) - 2;
|
||||
|
||||
l9p_pu16(msg, &size);
|
||||
l9p_pu16(msg, &stat->type);
|
||||
l9p_pu32(msg, &stat->dev);
|
||||
l9p_puqid(msg, &stat->qid);
|
||||
l9p_pu32(msg, &stat->mode);
|
||||
l9p_pu32(msg, &stat->atime);
|
||||
l9p_pu32(msg, &stat->mtime);
|
||||
l9p_pu64(msg, &stat->length);
|
||||
l9p_pustring(msg, &stat->name);
|
||||
l9p_pustring(msg, &stat->uid);
|
||||
l9p_pustring(msg, &stat->gid);
|
||||
l9p_pustring(msg, &stat->muid);
|
||||
}
|
||||
|
||||
int
|
||||
l9p_pufcall(struct l9p_message *msg, union l9p_fcall *fcall)
|
||||
{
|
||||
l9p_pu8(msg, &fcall->hdr.type);
|
||||
l9p_pu16(msg, &fcall->hdr.tag);
|
||||
|
||||
switch (fcall->hdr.type) {
|
||||
case L9P_TVERSION:
|
||||
case L9P_RVERSION:
|
||||
l9p_pu32(msg, &fcall->version.msize);
|
||||
l9p_pustring(msg, &fcall->version.version);
|
||||
break;
|
||||
case L9P_TAUTH:
|
||||
l9p_pu32(msg, &fcall->tauth.afid);
|
||||
l9p_pustring(msg, &fcall->tauth.uname);
|
||||
l9p_pustring(msg, &fcall->tauth.aname);
|
||||
break;
|
||||
case L9P_RAUTH:
|
||||
l9p_puqid(msg, &fcall->rauth.aqid);
|
||||
break;
|
||||
case L9P_RATTACH:
|
||||
l9p_puqid(msg, &fcall->rattach.qid);
|
||||
break;
|
||||
case L9P_TATTACH:
|
||||
l9p_pu32(msg, &fcall->hdr.fid);
|
||||
l9p_pu32(msg, &fcall->tattach.afid);
|
||||
l9p_pustring(msg, &fcall->tattach.uname);
|
||||
l9p_pustring(msg, &fcall->tattach.aname);
|
||||
break;
|
||||
case L9P_RERROR:
|
||||
l9p_pustring(msg, &fcall->error.ename);
|
||||
break;
|
||||
case L9P_TFLUSH:
|
||||
l9p_pu16(msg, &fcall->tflush.oldtag);
|
||||
break;
|
||||
case L9P_TWALK:
|
||||
l9p_pu32(msg, &fcall->hdr.fid);
|
||||
l9p_pu32(msg, &fcall->twalk.newfid);
|
||||
l9p_pustrings(msg, &fcall->twalk.nwname, fcall->twalk.wname,
|
||||
N(fcall->twalk.wname));
|
||||
break;
|
||||
case L9P_RWALK:
|
||||
l9p_puqids(msg, &fcall->rwalk.nwqid, fcall->rwalk.wqid,
|
||||
N(fcall->rwalk.wqid));
|
||||
break;
|
||||
case L9P_TOPEN:
|
||||
l9p_pu32(msg, &fcall->hdr.fid);
|
||||
l9p_pu8(msg, &fcall->topen.mode);
|
||||
break;
|
||||
case L9P_ROPEN:
|
||||
case L9P_RCREATE:
|
||||
l9p_puqid(msg, &fcall->ropen.qid);
|
||||
l9p_pu32(msg, &fcall->ropen.iounit);
|
||||
break;
|
||||
case L9P_TCREATE:
|
||||
l9p_pu32(msg, &fcall->hdr.fid);
|
||||
l9p_pustring(msg, &fcall->tcreate.name);
|
||||
l9p_pu32(msg, &fcall->tcreate.perm);
|
||||
l9p_pu8(msg, &fcall->tcreate.mode);
|
||||
break;
|
||||
case L9P_TREMOVE:
|
||||
l9p_pu32(msg, &fcall->hdr.fid);
|
||||
l9p_pu64(msg, &fcall->io.offset);
|
||||
l9p_pu32(msg, &fcall->io.count);
|
||||
break;
|
||||
case L9P_RREAD:
|
||||
l9p_pu32(msg, &fcall->io.count);
|
||||
l9p_pudata(msg, &fcall->io.data, fcall->io.count);
|
||||
break;
|
||||
case L9P_TWRITE:
|
||||
l9p_pu32(msg, &fcall->hdr.fid);
|
||||
l9p_pu64(msg, &fcall->io.offset);
|
||||
l9p_pu32(msg, &fcall->io.count);
|
||||
l9p_pudata(msg, &fcall->io.data, fcall->io.count);
|
||||
break;
|
||||
case L9P_RWRITE:
|
||||
l9p_pu32(msg, &fcall->io.count);
|
||||
break;
|
||||
case L9P_TCLUNK:
|
||||
case L9P_TSTAT:
|
||||
l9p_pu32(msg, &fcall->hdr.fid);
|
||||
break;
|
||||
case L9P_RSTAT:
|
||||
l9p_pu16(msg, &fcall->rstat.nstat);
|
||||
l9p_pudata(msg, (char**)&fcall->rstat.stat, fcall->rstat.nstat);
|
||||
break;
|
||||
case L9P_TWSTAT: {
|
||||
uint16_t size;
|
||||
l9p_pu32(msg, &fcall->hdr.fid);
|
||||
l9p_pu16(msg, &size);
|
||||
l9p_pustat(msg, &fcall->twstat.stat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
l9p_sizeof_stat(struct l9p_stat *stat) {
|
||||
return L9P_WORD /* size */
|
||||
+ L9P_WORD /* type */
|
||||
+ L9P_DWORD /* dev */
|
||||
+ QID_SIZE /* qid */
|
||||
+ 3 * L9P_DWORD /* mode, atime, mtime */
|
||||
+ L9P_DWORD /* length */
|
||||
+ STRING_SIZE(stat->name)
|
||||
+ STRING_SIZE(stat->uid)
|
||||
+ STRING_SIZE(stat->gid)
|
||||
+ STRING_SIZE(stat->muid);
|
||||
}
|
132
lib9p.h
Normal file
132
lib9p.h
Normal file
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIB9P_LIB9P_H
|
||||
#define LIB9P_LIB9P_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/queue.h>
|
||||
#include <pthread.h>
|
||||
#include "fcall.h"
|
||||
|
||||
#define L9P_ENOFID "FID does not exist"
|
||||
#define L9P_ENOFUNC "Function not implemented"
|
||||
#define L9P_EINTR "Interrupted"
|
||||
|
||||
enum l9p_pack_mode
|
||||
{
|
||||
L9P_PACK,
|
||||
L9P_UNPACK
|
||||
};
|
||||
|
||||
enum l9p_integer_type
|
||||
{
|
||||
L9P_BYTE = 1,
|
||||
L9P_WORD = 2,
|
||||
L9P_DWORD = 4,
|
||||
L9P_QWORD = 8
|
||||
};
|
||||
|
||||
struct l9p_message
|
||||
{
|
||||
enum l9p_pack_mode lm_mode;
|
||||
uint8_t *lm_buffer;
|
||||
uint8_t *lm_pos;
|
||||
uint8_t *lm_end;
|
||||
};
|
||||
|
||||
struct l9p_request
|
||||
{
|
||||
uint32_t lr_tag;
|
||||
union l9p_fcall lr_req;
|
||||
union l9p_fcall lr_resp;
|
||||
struct l9p_openfile *lr_fid;
|
||||
struct l9p_connection *lr_conn;
|
||||
pthread_t lr_thread;
|
||||
LIST_ENTRY(l9p_request) lr_link;
|
||||
};
|
||||
|
||||
struct l9p_openfile
|
||||
{
|
||||
char *lo_uid;
|
||||
void *lo_aux;
|
||||
uint32_t lo_fid;
|
||||
struct l9p_qid lo_qid;
|
||||
struct l9p_connection *lo_conn;
|
||||
LIST_ENTRY(l9p_openfile) lo_link;
|
||||
};
|
||||
|
||||
struct l9p_connection
|
||||
{
|
||||
struct l9p_server *lc_server;
|
||||
pthread_mutex_t lc_send_lock;
|
||||
void (*lc_send_request)(const void *, const size_t, void *);
|
||||
void *lc_send_request_aux;
|
||||
void *lc_softc;
|
||||
LIST_HEAD(, l9p_request) lc_requests;
|
||||
LIST_HEAD(, l9p_openfile) lc_files;
|
||||
LIST_ENTRY(l9p_connection) lc_link;
|
||||
};
|
||||
|
||||
struct l9p_server
|
||||
{
|
||||
struct l9p_backend *ls_backend;
|
||||
LIST_HEAD(, l9p_connection) ls_conns;
|
||||
};
|
||||
|
||||
struct l9p_backend
|
||||
{
|
||||
void *softc;
|
||||
void (*attach)(void *, struct l9p_request *);
|
||||
void (*clunk)(void *, struct l9p_request *);
|
||||
void (*create)(void *, struct l9p_request *);
|
||||
void (*flush)(void *, struct l9p_request *);
|
||||
void (*open)(void *, struct l9p_request *);
|
||||
void (*read)(void *, struct l9p_request *);
|
||||
void (*remove)(void *, struct l9p_request *);
|
||||
void (*stat)(void *, struct l9p_request *);
|
||||
void (*walk)(void *, struct l9p_request *);
|
||||
void (*write)(void *, struct l9p_request *);
|
||||
void (*wstat)(void *, struct l9p_request *);
|
||||
void (*freefid)(void *, struct l9p_openfile *);
|
||||
};
|
||||
|
||||
int l9p_pufcall(struct l9p_message *msg, union l9p_fcall *fcall);
|
||||
|
||||
int l9p_server_init(struct l9p_server **, struct l9p_backend *backend);
|
||||
|
||||
int l9p_connection_init(struct l9p_server *server, struct l9p_connection **conn);
|
||||
void l9p_connection_free(struct l9p_connection *conn);
|
||||
void l9p_connection_on_send_request(struct l9p_connection *conn, void (*cb)(void *, size_t, void *), void *);
|
||||
void l9p_connection_recv(struct l9p_connection *conn, void *buf, size_t len);
|
||||
void l9p_connection_close(struct l9p_connection *conn);
|
||||
struct l9p_openfile *l9p_connection_find_fid(struct l9p_connection *conn, uint32_t fid);
|
||||
struct l9p_request *l9p_connection_find_tag(struct l9p_connection *conn, uint32_t tag);
|
||||
void l9p_respond(struct l9p_request *req, const char *error);
|
||||
|
||||
#endif //LIB9P_LIB9P_H
|
41
log.c
Normal file
41
log.c
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include "log.h"
|
||||
|
||||
void
|
||||
l9p_logf(enum l9p_log_level level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(ap);
|
||||
}
|
41
log.h
Normal file
41
log.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIB9P_LOG_H
|
||||
#define LIB9P_LOG_H
|
||||
|
||||
enum l9p_log_level
|
||||
{
|
||||
L9P_DEBUG,
|
||||
L9P_INFO,
|
||||
L9P_WARNING,
|
||||
L9P_ERROR
|
||||
};
|
||||
|
||||
void l9p_logf(enum l9p_log_level level, const char *fmt, ...);
|
||||
|
||||
#endif /* LIB9P_LOG_H */
|
251
request.c
Normal file
251
request.c
Normal file
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "lib9p.h"
|
||||
#include "fcall.h"
|
||||
#include "log.h"
|
||||
|
||||
#define N(x) (sizeof(x) / sizeof(x[0]))
|
||||
|
||||
static void l9p_dispatch_tversion(struct l9p_request *req);
|
||||
static void l9p_dispatch_tattach(struct l9p_request *req);
|
||||
static void l9p_dispatch_tclunk(struct l9p_request *req);
|
||||
static void l9p_dispatch_tflush(struct l9p_request *req);
|
||||
static void l9p_dispatch_tcreate(struct l9p_request *req);
|
||||
static void l9p_dispatch_topen(struct l9p_request *req);
|
||||
static void l9p_dispatch_tread(struct l9p_request *req);
|
||||
static void l9p_dispatch_tremove(struct l9p_request *req);
|
||||
static void l9p_dispatch_tstat(struct l9p_request *req);
|
||||
static void l9p_dispatch_twalk(struct l9p_request *req);
|
||||
static void l9p_dispatch_twrite(struct l9p_request *req);
|
||||
static void l9p_dispatch_twstat(struct l9p_request *req);
|
||||
|
||||
static struct
|
||||
{
|
||||
enum l9p_ftype type;
|
||||
void (*handler)(struct l9p_request *);
|
||||
} l9p_handlers[] = {
|
||||
{L9P_TVERSION, l9p_dispatch_tversion},
|
||||
{L9P_TATTACH, l9p_dispatch_tattach},
|
||||
{L9P_TCLUNK, l9p_dispatch_tclunk},
|
||||
{L9P_TFLUSH, l9p_dispatch_tflush},
|
||||
{L9P_TCREATE, l9p_dispatch_tcreate},
|
||||
{L9P_TOPEN, l9p_dispatch_topen},
|
||||
{L9P_TREAD, l9p_dispatch_tread},
|
||||
{L9P_TWRITE, l9p_dispatch_twrite},
|
||||
{L9P_TREMOVE, l9p_dispatch_tremove},
|
||||
{L9P_TSTAT, l9p_dispatch_tstat},
|
||||
{L9P_TWALK, l9p_dispatch_twalk},
|
||||
{L9P_TWSTAT, l9p_dispatch_twstat}
|
||||
};
|
||||
|
||||
void
|
||||
l9p_dispatch_request(struct l9p_request *req)
|
||||
{
|
||||
struct l9p_connection *conn = req->lr_conn;
|
||||
int i;
|
||||
|
||||
l9p_logf(L9P_INFO, "new request of type %d", req->lr_req.hdr.type);
|
||||
req->lr_tag = req->lr_req.hdr.tag;
|
||||
|
||||
for (i = 0; i < N(l9p_handlers); i++) {
|
||||
if (req->lr_req.hdr.type == l9p_handlers[i].type) {
|
||||
l9p_handlers[i].handler(req);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
l9p_respond(struct l9p_request *req, const char *error)
|
||||
{
|
||||
struct l9p_connection *conn = req->lr_conn;
|
||||
struct l9p_message msg;
|
||||
void *buf = malloc(1024 * 1024);
|
||||
|
||||
msg.lm_buffer = buf;
|
||||
msg.lm_pos = buf;
|
||||
msg.lm_end = buf + (1024 * 1024);
|
||||
msg.lm_mode = L9P_PACK;
|
||||
|
||||
switch (req->lr_req.hdr.type) {
|
||||
case L9P_TVERSION:
|
||||
break;
|
||||
}
|
||||
|
||||
req->lr_resp.hdr.tag = req->lr_req.hdr.tag;
|
||||
|
||||
if (error == NULL)
|
||||
req->lr_resp.hdr.type = req->lr_req.hdr.type + 1;
|
||||
else {
|
||||
req->lr_resp.hdr.type = L9P_RERROR;
|
||||
req->lr_resp.error.ename = error;
|
||||
}
|
||||
|
||||
if (l9p_pufcall(&msg, &req->lr_resp) != 0) {
|
||||
|
||||
}
|
||||
|
||||
conn->lc_send_request(msg.lm_buffer, msg.lm_pos - msg.lm_buffer, conn->lc_send_request_aux);
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_dispatch_tversion(struct l9p_request *req)
|
||||
{
|
||||
if (!strcmp(req->lr_req.version.version, "9P"))
|
||||
req->lr_resp.version.version = "9P";
|
||||
else if (!strcmp(req->lr_req.version.version, "9P2000"))
|
||||
req->lr_resp.version.version = "9P2000";
|
||||
else
|
||||
req->lr_resp.version.version = "unknown";
|
||||
|
||||
req->lr_resp.version.msize = req->lr_resp.version.msize;
|
||||
l9p_respond(req, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_dispatch_tattach(struct l9p_request *req)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_dispatch_tclunk(struct l9p_request *req)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_dispatch_tflush(struct l9p_request *req)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_dispatch_tcreate(struct l9p_request *req)
|
||||
{
|
||||
struct l9p_connection *conn = req->lr_conn;
|
||||
struct l9p_openfile *fid;
|
||||
|
||||
if (l9p_connection_find_fid(conn, req->lr_req.tcreate.hdr.fid) != NULL) {
|
||||
l9p_respond(req, "x");
|
||||
return;
|
||||
}
|
||||
|
||||
fid = malloc(sizeof(struct l9p_openfile));
|
||||
fid->lo_fid = req->lr_req.tcreate.hdr.fid;
|
||||
fid->lo_conn = conn;
|
||||
LIST_INSERT_HEAD(&conn->lc_files, fid, lo_link);
|
||||
|
||||
conn->lc_server->ls_backend->create(conn->lc_server->ls_backend->softc, req);
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_dispatch_topen(struct l9p_request *req)
|
||||
{
|
||||
struct l9p_connection *conn = req->lr_conn;
|
||||
struct l9p_openfile *fid;
|
||||
|
||||
fid = l9p_connection_find_fid(conn, req->lr_req.topen.hdr.fid);
|
||||
if (!fid) {
|
||||
l9p_respond(req, L9P_ENOFID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!conn->lc_server->ls_backend->open) {
|
||||
l9p_respond(req, L9P_ENOFUNC);
|
||||
return;
|
||||
}
|
||||
|
||||
conn->lc_server->ls_backend->open(conn->lc_server->ls_backend->softc, req);
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_dispatch_tread(struct l9p_request *req)
|
||||
{
|
||||
struct l9p_connection *conn = req->lr_conn;
|
||||
struct l9p_openfile *fid;
|
||||
|
||||
fid = l9p_connection_find_fid(conn, req->lr_req.tcreate.hdr.fid);
|
||||
if (!fid) {
|
||||
l9p_respond(req, L9P_ENOFID);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_dispatch_tremove(struct l9p_request *req)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_dispatch_tstat(struct l9p_request *req)
|
||||
{
|
||||
struct l9p_connection *conn = req->lr_conn;
|
||||
struct l9p_openfile *fid;
|
||||
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_dispatch_twalk(struct l9p_request *req)
|
||||
{
|
||||
struct l9p_connection *conn = req->lr_conn;
|
||||
struct l9p_openfile *fid;
|
||||
|
||||
fid = l9p_connection_find_fid(conn, req->lr_req.twalk.hdr.fid);
|
||||
if (!fid) {
|
||||
l9p_respond(req, L9P_ENOFID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (req->lr_req.twalk.hdr.fid != req->lr_req.twalk.newfid) {
|
||||
|
||||
}
|
||||
|
||||
if (!conn->lc_server->ls_backend->walk) {
|
||||
l9p_respond(req, L9P_ENOFUNC);
|
||||
return;
|
||||
}
|
||||
|
||||
conn->lc_server->ls_backend->walk(conn->lc_server->ls_backend->softc, req);
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_dispatch_twrite(struct l9p_request *req)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_dispatch_twstat(struct l9p_request *req)
|
||||
{
|
||||
|
||||
}
|
256
transport/socket.c
Normal file
256
transport/socket.c
Normal file
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* Copyright 2016 Jakub Klama <jceel@FreeBSD.org>
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/event.h>
|
||||
#include <netdb.h>
|
||||
#include "../lib9p.h"
|
||||
#include "../log.h"
|
||||
#include "socket.h"
|
||||
|
||||
static int l9p_socket_readmsg(int, void **, size_t *);
|
||||
static void l9p_socket_sendmsg(void *, size_t, void *);
|
||||
static void *l9p_socket_thread(void *);
|
||||
static int xread(int, void *, size_t);
|
||||
static int xwrite(int, void *, size_t);
|
||||
|
||||
struct l9p_socket_softc
|
||||
{
|
||||
struct l9p_connection *ls_conn;
|
||||
struct sockaddr ls_sockaddr;
|
||||
socklen_t ls_socklen;
|
||||
pthread_t ls_thread;
|
||||
int ls_fd;
|
||||
};
|
||||
|
||||
int
|
||||
l9p_start_server(struct l9p_server *server, const char *host, const char *port)
|
||||
{
|
||||
struct addrinfo *res, *res0, hints;
|
||||
struct kevent kev[2];
|
||||
struct kevent event[2];
|
||||
int err, kq, i, val, evs, nsockets = 0;
|
||||
int sockets[2];
|
||||
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = PF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
err = getaddrinfo(host, port, &hints, &res0);
|
||||
|
||||
if (err)
|
||||
return (-1);
|
||||
|
||||
for (res = res0; res; res = res->ai_next) {
|
||||
int s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
|
||||
|
||||
val = 1;
|
||||
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
||||
|
||||
if (s < 0)
|
||||
continue;
|
||||
|
||||
if (bind(s, res->ai_addr, res->ai_addrlen) < 0) {
|
||||
close(s);
|
||||
continue;
|
||||
}
|
||||
|
||||
sockets[nsockets] = s;
|
||||
EV_SET(&kev[nsockets++], s, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
|
||||
listen(s, 10);
|
||||
}
|
||||
|
||||
kq = kqueue();
|
||||
kevent(kq, kev, nsockets, NULL, 0, NULL);
|
||||
|
||||
for (;;) {
|
||||
evs = kevent(kq, NULL, 0, event, nsockets, NULL);
|
||||
if (evs < 0) {
|
||||
|
||||
}
|
||||
|
||||
for (i = 0; i < evs; i++) {
|
||||
struct sockaddr client_addr;
|
||||
socklen_t client_addr_len;
|
||||
int news = accept(event[i].ident, &client_addr,
|
||||
&client_addr_len);
|
||||
|
||||
if (news < 0) {
|
||||
l9p_logf(L9P_WARNING, "accept(): %s", strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
l9p_socket_accept(server, news, &client_addr,
|
||||
client_addr_len);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
l9p_socket_accept(struct l9p_server *server, int conn_fd,
|
||||
struct sockaddr *client_addr, socklen_t client_addr_len)
|
||||
{
|
||||
struct l9p_socket_softc *sc;
|
||||
struct l9p_connection *conn;
|
||||
char host[NI_MAXHOST + 1];
|
||||
char serv[NI_MAXSERV + 1];
|
||||
int err;
|
||||
|
||||
err = getnameinfo(client_addr, client_addr_len, host, NI_MAXHOST, serv,
|
||||
NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV);
|
||||
|
||||
if (err != 0) {
|
||||
l9p_logf(L9P_WARNING, "cannot look up client name: %s",
|
||||
gai_strerror(err));
|
||||
} else
|
||||
l9p_logf(L9P_INFO, "new connection from %s:%s", host, serv);
|
||||
|
||||
if (l9p_connection_init(server, &conn) != 0) {
|
||||
l9p_logf(L9P_ERROR, "cannot create new connection");
|
||||
}
|
||||
|
||||
sc = malloc(sizeof(sc));
|
||||
sc->ls_conn = conn;
|
||||
sc->ls_fd = conn_fd;
|
||||
|
||||
l9p_connection_on_send_request(conn, l9p_socket_sendmsg, sc);
|
||||
pthread_create(&sc->ls_thread, NULL, l9p_socket_thread, sc);
|
||||
}
|
||||
|
||||
static void *
|
||||
l9p_socket_thread(void *arg)
|
||||
{
|
||||
struct l9p_socket_softc *sc = (struct l9p_socket_softc *)arg;
|
||||
void *buf;
|
||||
size_t length;
|
||||
|
||||
for (;;) {
|
||||
if (l9p_socket_readmsg(sc->ls_fd, &buf, &length) != 0)
|
||||
break;
|
||||
|
||||
l9p_connection_recv(sc->ls_conn, buf, length);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static int
|
||||
l9p_socket_readmsg(int fd, void **buf, size_t *size)
|
||||
{
|
||||
uint32_t msize;
|
||||
void *buffer;
|
||||
|
||||
if (xread(fd, &msize, sizeof(uint32_t)) != sizeof(uint32_t)) {
|
||||
l9p_logf(L9P_ERROR, "short read: %s", strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
msize -= sizeof(msize);
|
||||
buffer = malloc(msize);
|
||||
|
||||
if (xread(fd, buffer, msize) != msize) {
|
||||
l9p_logf(L9P_ERROR, "short read: %s", strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
*size = msize;
|
||||
*buf = buffer;
|
||||
l9p_logf(L9P_INFO, "read complete message, size=%d", msize);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
l9p_socket_sendmsg(void *buf, size_t len, void *arg)
|
||||
{
|
||||
struct l9p_socket_softc *sc = (struct l9p_socket_softc *)arg;
|
||||
uint32_t msize = (uint32_t)len + sizeof(uint32_t);
|
||||
|
||||
if (xwrite(sc->ls_fd, &msize, sizeof(uint32_t) != sizeof(uint32_t))) {
|
||||
l9p_logf(L9P_ERROR, "short write: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
if (xwrite(sc->ls_fd, buf, len) != len) {
|
||||
l9p_logf(L9P_ERROR, "short write: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
xread(int fd, void *buf, size_t count)
|
||||
{
|
||||
size_t done = 0;
|
||||
int ret;
|
||||
|
||||
while (done < count) {
|
||||
ret = read(fd, buf + done, count - done);
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
return (done);
|
||||
|
||||
done += ret;
|
||||
}
|
||||
|
||||
return (done);
|
||||
}
|
||||
|
||||
static int
|
||||
xwrite(int fd, void *buf, size_t count)
|
||||
{
|
||||
size_t done = 0;
|
||||
int ret;
|
||||
|
||||
while (done < count) {
|
||||
ret = write(fd, buf + done, count - done);
|
||||
if (ret < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
return (done);
|
||||
|
||||
done += ret;
|
||||
}
|
||||
|
||||
return (done);
|
||||
}
|
17
transport/socket.h
Normal file
17
transport/socket.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
//
|
||||
// Created by Jakub Klama on 28.12.2015.
|
||||
//
|
||||
|
||||
#ifndef LIB9P_SOCKET_H
|
||||
#define LIB9P_SOCKET_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include "../lib9p.h"
|
||||
|
||||
int l9p_start_server(struct l9p_server *server, const char *host,
|
||||
const char *port);
|
||||
void l9p_socket_accept(struct l9p_server *server, int conn_fd,
|
||||
struct sockaddr *client_addr, socklen_t client_addr_len);
|
||||
|
||||
#endif //LIB9P_SOCKET_H
|
Loading…
Add table
Reference in a new issue