extend the ixp.read() function
[wmiirc-lua.git] / luaixp / lixp_util.c
blob004282e757aeb6101befea7e9f6bf06d42bcd9d2
1 #include <stdio.h>
2 #include <string.h>
3 #include <errno.h>
4 #include <time.h>
5 #include <stdarg.h>
6 #include <stdlib.h>
8 #include <ixp.h>
9 #include <lua.h>
10 #include <lauxlib.h>
12 #include "lixp_util.h"
16 * Copy src into destination escaping %'s into %%'s;
18 * NOTE: destination buffer must be twice as large as the source.
20 static inline void copy_escaping_fmt(char *dest, const char *src)
22 char *d = dest, *pc;
23 const char *s = src;
25 while ((pc = strchr (s, '%'))) {
26 int len = pc - s + 1;
27 memcpy(d, s, len);
28 d += len;
29 s += len;
30 *(d++) = '%';
33 strcpy(d, s);
36 /* ------------------------------------------------------------------------
37 * error helper
39 int lixp_pusherrorf(lua_State *L, const char *fmt, ...)
41 va_list ap;
43 lua_pushnil(L);
44 if (errno) {
45 char *_fmt;
46 const char *estr;
47 size_t elen;
49 estr = strerror(errno);
50 elen = strlen(estr);
52 _fmt = malloc(strlen(fmt) + 2 + (elen*2) + 1);
53 if (!_fmt)
54 goto do_short_fmt;
56 copy_escaping_fmt(_fmt, estr);
57 strcat(_fmt, "; ");
58 strcat(_fmt, fmt);
60 va_start(ap, fmt);
61 lua_pushvfstring(L, _fmt, ap);
62 va_end(ap);
64 free(_fmt);
66 lua_pushnumber(L, errno);
67 return 3;
70 do_short_fmt:
71 va_start(ap, fmt);
72 lua_pushvfstring(L, "%s", ap);
73 va_end(ap);
74 return 2;
77 int lixp_pusherror(lua_State *L, const char *info)
79 if (info==NULL) {
80 lua_pushnil(L);
81 lua_pushstring(L, strerror(errno));
82 lua_pushnumber(L, errno);
83 return 3;
86 return lixp_pusherrorf(L, "%s", info);
89 /* ------------------------------------------------------------------------
90 * write a buffer to an IXP file
92 int lixp_write_data (IxpCFid *fid, const char *data, size_t data_len)
94 size_t left;
95 off_t ofs = 0;
97 left = data_len;
98 while (left) {
99 int rc = ixp_write(fid, (char*)data + ofs, left);
100 if (rc < 0)
101 return rc;
103 else if (rc > left)
104 return -ENXIO;
106 left -= rc;
107 ofs += rc;
110 return data_len;
113 /* ------------------------------------------------------------------------
114 * dump IXP status structure to lua table
116 static void setrwx(long m, char *s)
118 static char *modes[] = {
119 "---", "--x", "-w-",
120 "-wx", "r--", "r-x",
121 "rw-", "rwx",
123 strncpy(s, modes[m], 3);
126 static void build_modestr(char *buf, const struct IxpStat *stat)
128 buf[0]='-';
129 if(stat->mode & P9_DMDIR)
130 buf[0]='d';
131 buf[1]='-';
132 setrwx((stat->mode >> 6) & 7, &buf[2]);
133 setrwx((stat->mode >> 3) & 7, &buf[5]);
134 setrwx((stat->mode >> 0) & 7, &buf[8]);
135 buf[11] = 0;
138 static void build_timestr(char *buf, const struct IxpStat *stat)
140 ctime_r((time_t*)&stat->mtime, buf);
141 buf[strlen(buf) - 1] = '\0';
145 #define setfield(type,name,value) \
146 lua_pushstring (L, name); \
147 lua_push##type (L, value); \
148 lua_settable (L, -3);
149 int lixp_pushstat (lua_State *L, const struct IxpStat *stat)
151 static char buf[32];
152 lua_newtable (L);
154 setfield(number, "type", stat->type);
155 setfield(number, "dev", stat->dev);
156 //setfield(Qid, "qid", stat->qid); // TODO: what is this?
157 setfield(number, "mode", stat->mode);
158 setfield(number, "atime", stat->atime);
159 setfield(number, "mtime", stat->mtime);
160 setfield(number, "length", stat->length);
161 setfield(string, "name", stat->name);
162 setfield(string, "uid", stat->uid);
163 setfield(string, "gid", stat->gid);
164 setfield(string, "muid", stat->muid);
166 build_modestr(buf, stat);
167 setfield(string, "modestr", buf);
169 build_timestr(buf, stat);
170 setfield(string, "timestr", buf);
172 return 1;