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:
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);