wmii

git clone git://oldgit.suckless.org/wmii/
Log | Files | Refs | README | LICENSE

commit a725d3d6b3a01f8d1f307d03ced50468753577c8
parent 903d558f0845c84e5abec0b05321bf6934d81943
Author: Anselm R. Garbe <garbeam@wmii.de>
Date:   Tue, 23 May 2006 08:17:42 +0200

added wmiir ls, wmiir read behaves like 9p read now, to get full info use wmiir ls -l


Diffstat:
TODO.wmii-4 | 2--
cmd/wmiir.c | 113++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------------
libixp/client.c | 37+++++++++++++++++++++++++++----------
libixp/ixp.h | 4+++-
4 files changed, 104 insertions(+), 52 deletions(-)

diff --git a/TODO.wmii-4 b/TODO.wmii-4 @@ -25,8 +25,6 @@ allowing explicit coordinates, instead additionally resize +/-<w> +/-<h> and move +/-<x> +/-<y> actions are needed in the associated ctl devices of clients. -- add wmiir ls (read should have same semantic as in 9p), output without - details, add -l for details like in ls of Plan 9 - remove internal labels, now tagging seems easy and straightforward that they THINK: We'll need CreateTag, DestroyTag, UnfocusTag, FocusTag and the event loop in wmiirc must be before TAGGING can be externalized again diff --git a/cmd/wmiir.c b/cmd/wmiir.c @@ -19,7 +19,8 @@ static char version[] = "wmiir - " VERSION ", (C)opyright MMIV-MMVI Anselm R. Ga static void usage() { - fprintf(stderr, "%s", "usage: wmiir [-a <address>] [-v] create | read | remove | write <file>\n"); + fprintf(stderr, "%s", + "usage: wmiir [-a <address>] [-v] create | read | ls [-l] | remove | write <file>\n"); exit(1); } @@ -69,7 +70,7 @@ xwrite(char *file, unsigned char mode) { /* open */ unsigned int fid = c.root_fid << 2; - if(ixp_client_open(&c, fid, file, mode) == -1) { + if(ixp_client_walkopen(&c, fid, file, mode) == -1) { fprintf(stderr, "wmiir: cannot open file '%s': %s\n", file, c.errstr); return -1; } @@ -132,7 +133,21 @@ str_of_time(unsigned int val) } static void -xls(void *result, unsigned int msize) +print_stat(Stat *s, int details) +{ + if(details) + fprintf(stdout, "%s %s %s %5llu %s %s\n", str_of_mode(s->mode), + s->uid, s->gid, s->length, str_of_time(s->mtime), s->name); + else { + if(s->mode & IXP_DMDIR) + fprintf(stdout, "%s/\n", s->name); + else + fprintf(stdout, "%s\n", s->name); + } +} + +static void +xls(void *result, unsigned int msize, int details) { unsigned int n = 0, i = 0; void *p = result; @@ -151,62 +166,73 @@ xls(void *result, unsigned int msize) } while(p - result < msize); qsort(dir, n, sizeof(Stat), comp_stat); - for(i = 0; i < n; i++) { - fprintf(stdout, "%s %s %s %5llu %s %s\n", str_of_mode(dir[i].mode), - dir[i].uid, dir[i].gid, dir[i].length, - str_of_time(dir[i].mtime), dir[i].name); - } + for(i = 0; i < n; i++) + print_stat(&dir[i], details); free(dir); + fflush(stdout); +} + +static int +xdir(char *file, int details) +{ + unsigned int fid = c.root_fid << 2; + int count; + static unsigned char result[IXP_MAX_MSG]; + void *data = nil; + unsigned long long offset = 0; + + if(ixp_client_stat(&c, fid, file) == -1) { + fprintf(stderr, "wmiir: cannot stat file '%s': %s\n", file, c.errstr); + return -1; + } + if(!(c.fcall.stat.mode & IXP_DMDIR)) { + print_stat(&c.fcall.stat, details); + fflush(stdout); + return 0; + } + + /* directory */ + if(ixp_client_open(&c, fid, IXP_OREAD) == -1) { + fprintf(stderr, "wmiir: cannot open directory '%s': %s\n", file, c.errstr); + return -1; + } + while((count = ixp_client_read(&c, fid, offset, result, IXP_MAX_MSG)) > 0) { + if(!(data = realloc(data, offset + count))) { + fprintf(stderr, "wmiir: %s\n", "Out of memory in xdir\n"); + return -1; + } + memcpy(data + offset, result, count); + offset += count; + } + if(count == -1) { + fprintf(stderr, "wmiir: cannot read directory '%s': %s\n", file, c.errstr); + return -1; + } + xls(data, offset + count, details); + return ixp_client_close(&c, fid); } static int xread(char *file) { unsigned int fid = c.root_fid << 2; - int count, is_directory = 0; + int count; static unsigned char result[IXP_MAX_MSG]; - void *dircontent = nil; - unsigned int dircontentsz = 0; - unsigned int ndircontent = 0; unsigned long long offset = 0; - if(ixp_client_open(&c, fid, file, IXP_OREAD) == -1) { + if(ixp_client_walkopen(&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); while((count = ixp_client_read(&c, fid, offset, result, IXP_MAX_MSG)) > 0) { - if(is_directory) { - if(ndircontent + count > dircontentsz) { - void *tmp = dircontent; - if(!dircontentsz) - dircontentsz = IXP_MAX_MSG; - else - dircontentsz *= 2; - dircontent = cext_emallocz(dircontentsz); - if(tmp) { - memcpy(dircontent, tmp, ndircontent); - free(tmp); - } - } - memcpy(dircontent + ndircontent, result, count); - ndircontent += count; - } - else { - unsigned int i; - for(i = 0; i < count; i++) - fputc(result[i], stdout); - fflush(stdout); - } + write(0, result, count); offset += count; } if(count == -1) { fprintf(stderr, "wmiir: cannot read file/directory '%s': %s\n", file, c.errstr); return -1; } - if(is_directory && ndircontent) - xls(dircontent, ndircontent); return ixp_client_close(&c, fid); } @@ -226,7 +252,7 @@ xremove(char *file) int main(int argc, char *argv[]) { - int ret = 0, i = 0; + int ret = 0, i = 0, details = 0; char *cmd, *file, *address = getenv("WMII_ADDRESS"); /* command line args */ @@ -252,6 +278,13 @@ main(int argc, char *argv[]) } cmd = argv[argc - 2]; file = argv[argc - 1]; + if((details = !strncmp(cmd, "-l", 3))) { + if(argc < 3) + usage(); + if(strncmp(argv[argc - 3], "ls", 3)) + usage(); + cmd = argv[argc - 3]; + } if(!address) { fprintf(stderr, "%s", "wmiir: error: $WMII_ADDRESS not set\n"); @@ -265,6 +298,8 @@ main(int argc, char *argv[]) if(!strncmp(cmd, "create", 7)) ret = xcreate(file); + else if(!strncmp(cmd, "ls", 3)) + ret = xdir(file, details); else if(!strncmp(cmd, "read", 5)) ret = xread(file); else if(!strncmp(cmd, "remove", 7)) diff --git a/libixp/client.c b/libixp/client.c @@ -13,7 +13,7 @@ #include "ixp.h" int -ixp_client_do_fcall(IXPClient * c) +ixp_client_do_fcall(IXPClient *c) { static unsigned char msg[IXP_MAX_MSG]; unsigned int msize = ixp_fcall2msg(msg, &c->fcall, IXP_MAX_MSG); @@ -73,7 +73,7 @@ ixp_client_dial(IXPClient *c, char *sockfile, unsigned int rootfid) } int -ixp_client_remove(IXPClient * c, unsigned int newfid, char *filepath) +ixp_client_remove(IXPClient *c, unsigned int newfid, char *filepath) { if(ixp_client_walk(c, newfid, filepath) == -1) return -1; @@ -84,7 +84,7 @@ ixp_client_remove(IXPClient * c, unsigned int newfid, char *filepath) } int -ixp_client_create(IXPClient * c, unsigned int dirfid, char *name, +ixp_client_create(IXPClient *c, unsigned int dirfid, char *name, unsigned int perm, unsigned char mode) { c->fcall.id = TCREATE; @@ -97,7 +97,7 @@ ixp_client_create(IXPClient * c, unsigned int dirfid, char *name, } int -ixp_client_walk(IXPClient * c, unsigned int newfid, char *filepath) +ixp_client_walk(IXPClient *c, unsigned int newfid, char *filepath) { unsigned int i; char *wname[IXP_MAX_WELEM]; @@ -115,12 +115,20 @@ ixp_client_walk(IXPClient * c, unsigned int newfid, char *filepath) } int -ixp_client_open(IXPClient * c, unsigned int newfid, char *filepath, - unsigned char mode) +ixp_client_stat(IXPClient *c, unsigned int newfid, char *filepath) { if(ixp_client_walk(c, newfid, filepath) == -1) return -1; + c->fcall.id = TSTAT; + c->fcall.tag = IXP_NOTAG; + c->fcall.fid = newfid; + return ixp_client_do_fcall(c); +} + +int +ixp_client_open(IXPClient *c, unsigned int newfid, unsigned char mode) +{ c->fcall.id = TOPEN; c->fcall.tag = IXP_NOTAG; c->fcall.fid = newfid; @@ -129,7 +137,16 @@ ixp_client_open(IXPClient * c, unsigned int newfid, char *filepath, } int -ixp_client_read(IXPClient * c, unsigned int fid, unsigned long long offset, +ixp_client_walkopen(IXPClient *c, unsigned int newfid, char *filepath, + unsigned char mode) +{ + if(ixp_client_walk(c, newfid, filepath) == -1) + return -1; + return ixp_client_open(c, newfid, mode); +} + +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; @@ -146,7 +163,7 @@ ixp_client_read(IXPClient * c, unsigned int fid, unsigned long long offset, } int -ixp_client_write(IXPClient * c, unsigned int fid, +ixp_client_write(IXPClient *c, unsigned int fid, unsigned long long offset, unsigned int count, unsigned char *data) { @@ -166,7 +183,7 @@ ixp_client_write(IXPClient * c, unsigned int fid, } int -ixp_client_close(IXPClient * c, unsigned int fid) +ixp_client_close(IXPClient *c, unsigned int fid) { c->fcall.id = TCLUNK; c->fcall.tag = IXP_NOTAG; @@ -175,7 +192,7 @@ ixp_client_close(IXPClient * c, unsigned int fid) } void -ixp_client_hangup(IXPClient * c) +ixp_client_hangup(IXPClient *c) { /* session finished, now shutdown */ if(c->fd) { diff --git a/libixp/ixp.h b/libixp/ixp.h @@ -196,8 +196,10 @@ 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, +int ixp_client_stat(IXPClient *c, unsigned int newfid, char *filepath); +int ixp_client_walkopen(IXPClient *c, unsigned int newfid, char *filepath, unsigned char mode); +int ixp_client_open(IXPClient *c, unsigned int newfid, unsigned char mode); int ixp_client_read(IXPClient *c, unsigned int fid, unsigned long long offset, void *result, unsigned int res_len);