Root/package/lua/patches/400-luaposix_5.1.4-embedded.patch

1--- a/src/Makefile
2+++ b/src/Makefile
3@@ -12,7 +12,7 @@ CFLAGS= -O2 -Wall $(MYCFLAGS)
4 AR= ar rcu
5 RANLIB= ranlib
6 RM= rm -f
7-LIBS= -lm $(MYLIBS)
8+LIBS= -lm -lcrypt $(MYLIBS)
9 
10 MYCFLAGS=
11 MYLDFLAGS=
12@@ -29,7 +29,7 @@ CORE_O= lapi.o lcode.o ldebug.o ldo.o ld
13     lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \
14     lundump.o lvm.o lzio.o lnum.o
15 LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \
16- lstrlib.o loadlib.o linit.o
17+ lstrlib.o loadlib.o linit.o lposix.o
18 
19 LUA_T= lua
20 LUA_O= lua.o
21--- a/src/linit.c
22+++ b/src/linit.c
23@@ -23,6 +23,7 @@ static const luaL_Reg lualibs[] = {
24   {LUA_STRLIBNAME, luaopen_string},
25   {LUA_MATHLIBNAME, luaopen_math},
26   {LUA_DBLIBNAME, luaopen_debug},
27+ {LUA_POSIXLIBNAME, luaopen_posix},
28   {NULL, NULL}
29 };
30 
31--- /dev/null
32+++ b/src/lposix.c
33@@ -0,0 +1,1139 @@
34+/*
35+* lposix.c
36+* POSIX library for Lua 5.1.
37+* Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br>
38+* 07 Apr 2006 23:17:49
39+* Clean up and bug fixes by Leo Razoumov <slonik.az@gmail.com> 2006-10-11 <!LR>
40+* Based on original by Claudio Terra for Lua 3.x.
41+* With contributions by Roberto Ierusalimschy.
42+*/
43+
44+#include <sys/stat.h>
45+#include <sys/times.h>
46+#include <sys/types.h>
47+#include <sys/utsname.h>
48+#include <sys/wait.h>
49+
50+#include <dirent.h>
51+#include <errno.h>
52+#include <fcntl.h>
53+#include <glob.h>
54+#include <grp.h>
55+#include <libgen.h>
56+#include <limits.h>
57+#include <poll.h>
58+#include <pwd.h>
59+#include <signal.h>
60+#include <stdio.h>
61+#include <stdlib.h>
62+#include <string.h>
63+#include <syslog.h>
64+#include <time.h>
65+#include <unistd.h>
66+#include <utime.h>
67+
68+#define MYNAME "posix"
69+#define MYVERSION MYNAME " library for " LUA_VERSION " / Jan 2008"
70+
71+#ifndef ENABLE_SYSLOG
72+#define ENABLE_SYSLOG 1
73+#endif
74+
75+#include "lua.h"
76+#include "lualib.h"
77+#include "lauxlib.h"
78+
79+#include "modemuncher.c"
80+
81+/* compatibility with Lua 5.0 */
82+#ifndef LUA_VERSION_NUM
83+static int luaL_checkoption (lua_State *L, int narg, const char *def,
84+ const char *const lst[]) {
85+ const char *name = (def) ? luaL_optstring(L, narg, def) :
86+ luaL_checkstring(L, narg);
87+ int i = luaL_findstring(name, lst);
88+ if (i == -1)
89+ luaL_argerror(L, narg, lua_pushfstring(L, "invalid option '%s'", name));
90+ return i;
91+}
92+#define lua_pushinteger lua_pushnumber
93+#define lua_createtable(L,a,r) lua_newtable(L)
94+#define LUA_FILEHANDLE "FILE*"
95+
96+#define lua_setfield(l,i,k)
97+#define lua_getfield(l,i,k)
98+
99+#endif
100+
101+static const struct { char c; mode_t b; } M[] =
102+{
103+ {'r', S_IRUSR}, {'w', S_IWUSR}, {'x', S_IXUSR},
104+ {'r', S_IRGRP}, {'w', S_IWGRP}, {'x', S_IXGRP},
105+ {'r', S_IROTH}, {'w', S_IWOTH}, {'x', S_IXOTH},
106+};
107+
108+
109+static void pushmode(lua_State *L, mode_t mode)
110+{
111+ char m[9];
112+ int i;
113+ for (i=0; i<9; i++) m[i]= (mode & M[i].b) ? M[i].c : '-';
114+ if (mode & S_ISUID) m[2]= (mode & S_IXUSR) ? 's' : 'S';
115+ if (mode & S_ISGID) m[5]= (mode & S_IXGRP) ? 's' : 'S';
116+ lua_pushlstring(L, m, 9);
117+}
118+
119+typedef void (*Selector)(lua_State *L, int i, const void *data);
120+
121+static int doselection(lua_State *L, int i, int n,
122+ const char *const S[],
123+ Selector F,
124+ const void *data)
125+{
126+ if (lua_isnone(L, i) || lua_istable(L, i))
127+ {
128+ int j;
129+ if (lua_isnone(L, i)) lua_createtable(L,0,n); else lua_settop(L, i);
130+ for (j=0; S[j]!=NULL; j++)
131+ {
132+ lua_pushstring(L, S[j]);
133+ F(L, j, data);
134+ lua_settable(L, -3);
135+ }
136+ return 1;
137+ }
138+ else
139+ {
140+ int k,n=lua_gettop(L);
141+ for (k=i; k<=n; k++)
142+ {
143+ int j=luaL_checkoption(L, k, NULL, S);
144+ F(L, j, data);
145+ lua_replace(L, k);
146+ }
147+ return n-i+1;
148+ }
149+}
150+#define doselection(L,i,S,F,d) (doselection)(L,i,sizeof(S)/sizeof(*S)-1,S,F,d)
151+
152+static int pusherror(lua_State *L, const char *info)
153+{
154+ lua_pushnil(L);
155+ if (info==NULL)
156+ lua_pushstring(L, strerror(errno));
157+ else
158+ lua_pushfstring(L, "%s: %s", info, strerror(errno));
159+ lua_pushinteger(L, errno);
160+ return 3;
161+}
162+
163+static int pushresult(lua_State *L, int i, const char *info)
164+{
165+ if (i==-1) return pusherror(L, info);
166+ lua_pushinteger(L, i);
167+ return 1;
168+}
169+
170+static void badoption(lua_State *L, int i, const char *what, int option)
171+{
172+ luaL_argerror(L, 2,
173+ lua_pushfstring(L, "unknown %s option '%c'", what, option));
174+}
175+
176+static uid_t mygetuid(lua_State *L, int i)
177+{
178+ if (lua_isnone(L, i))
179+ return -1;
180+ else if (lua_isnumber(L, i))
181+ return (uid_t) lua_tonumber(L, i);
182+ else if (lua_isstring(L, i))
183+ {
184+ struct passwd *p=getpwnam(lua_tostring(L, i));
185+ return (p==NULL) ? -1 : p->pw_uid;
186+ }
187+ else
188+ return luaL_typerror(L, i, "string or number");
189+}
190+
191+static gid_t mygetgid(lua_State *L, int i)
192+{
193+ if (lua_isnone(L, i))
194+ return -1;
195+ else if (lua_isnumber(L, i))
196+ return (gid_t) lua_tonumber(L, i);
197+ else if (lua_isstring(L, i))
198+ {
199+ struct group *g=getgrnam(lua_tostring(L, i));
200+ return (g==NULL) ? -1 : g->gr_gid;
201+ }
202+ else
203+ return luaL_typerror(L, i, "string or number");
204+}
205+
206+
207+static int Perrno(lua_State *L) /** errno([n]) */
208+{
209+ int n = luaL_optint(L, 1, errno);
210+ lua_pushstring(L, strerror(n));
211+ lua_pushinteger(L, n);
212+ return 2;
213+}
214+
215+
216+static int Pbasename(lua_State *L) /** basename(path) */
217+{
218+ char b[PATH_MAX];
219+ size_t len;
220+ const char *path = luaL_checklstring(L, 1, &len);
221+ if (len>=sizeof(b)) luaL_argerror(L, 1, "too long");
222+ lua_pushstring(L, basename(strcpy(b,path)));
223+ return 1;
224+}
225+
226+
227+static int Pdirname(lua_State *L) /** dirname(path) */
228+{
229+ char b[PATH_MAX];
230+ size_t len;
231+ const char *path = luaL_checklstring(L, 1, &len);
232+ if (len>=sizeof(b)) luaL_argerror(L, 1, "too long");
233+ lua_pushstring(L, dirname(strcpy(b,path)));
234+ return 1;
235+}
236+
237+
238+static int Pdir(lua_State *L) /** dir([path]) */
239+{
240+ const char *path = luaL_optstring(L, 1, ".");
241+ DIR *d = opendir(path);
242+ if (d == NULL)
243+ return pusherror(L, path);
244+ else
245+ {
246+ int i;
247+ struct dirent *entry;
248+ lua_newtable(L);
249+ for (i=1; (entry = readdir(d)) != NULL; i++)
250+ {
251+ lua_pushstring(L, entry->d_name);
252+ lua_rawseti(L, -2, i);
253+ }
254+ closedir(d);
255+ lua_pushinteger(L, i-1);
256+ return 2;
257+ }
258+}
259+
260+static int Pglob(lua_State *L) /** glob(pattern) */
261+{
262+ const char *pattern = luaL_optstring(L, 1, "*");
263+ glob_t globres;
264+
265+ if (glob(pattern, 0, NULL, &globres))
266+ return pusherror(L, pattern);
267+ else
268+ {
269+ int i;
270+ lua_newtable(L);
271+ for (i=1; i<=globres.gl_pathc; i++) {
272+ lua_pushstring(L, globres.gl_pathv[i-1]);
273+ lua_rawseti(L, -2, i);
274+ }
275+ globfree(&globres);
276+ return 1;
277+ }
278+}
279+
280+static int aux_files(lua_State *L)
281+{
282+ DIR **p = (DIR **)lua_touserdata(L, lua_upvalueindex(1));
283+ DIR *d = *p;
284+ struct dirent *entry;
285+ if (d == NULL) return 0;
286+ entry = readdir(d);
287+ if (entry == NULL)
288+ {
289+ closedir(d);
290+ *p=NULL;
291+ return 0;
292+ }
293+ else
294+ {
295+ lua_pushstring(L, entry->d_name);
296+ return 1;
297+ }
298+}
299+
300+static int dir_gc (lua_State *L)
301+{
302+ DIR *d = *(DIR **)lua_touserdata(L, 1);
303+ if (d!=NULL) closedir(d);
304+ return 0;
305+}
306+
307+static int Pfiles(lua_State *L) /** files([path]) */
308+{
309+ const char *path = luaL_optstring(L, 1, ".");
310+ DIR **d = (DIR **)lua_newuserdata(L, sizeof(DIR *));
311+ if (luaL_newmetatable(L, MYNAME " dir handle"))
312+ {
313+ lua_pushliteral(L, "__gc");
314+ lua_pushcfunction(L, dir_gc);
315+ lua_settable(L, -3);
316+ }
317+ lua_setmetatable(L, -2);
318+ *d = opendir(path);
319+ if (*d == NULL) return pusherror(L, path);
320+ lua_pushcclosure(L, aux_files, 1);
321+ return 1;
322+}
323+
324+
325+static int Pgetcwd(lua_State *L) /** getcwd() */
326+{
327+ char b[PATH_MAX];
328+ if (getcwd(b, sizeof(b)) == NULL) return pusherror(L, ".");
329+ lua_pushstring(L, b);
330+ return 1;
331+}
332+
333+
334+static int Pmkdir(lua_State *L) /** mkdir(path) */
335+{
336+ const char *path = luaL_checkstring(L, 1);
337+ return pushresult(L, mkdir(path, 0777), path);
338+}
339+
340+
341+static int Pchdir(lua_State *L) /** chdir(path) */
342+{
343+ const char *path = luaL_checkstring(L, 1);
344+ return pushresult(L, chdir(path), path);
345+}
346+
347+static int Prmdir(lua_State *L) /** rmdir(path) */
348+{
349+ const char *path = luaL_checkstring(L, 1);
350+ return pushresult(L, rmdir(path), path);
351+}
352+
353+
354+static int Punlink(lua_State *L) /** unlink(path) */
355+{
356+ const char *path = luaL_checkstring(L, 1);
357+ return pushresult(L, unlink(path), path);
358+}
359+
360+static int Plink(lua_State *L) /** link(old,new,[symbolic]) */
361+{
362+ const char *oldpath = luaL_checkstring(L, 1);
363+ const char *newpath = luaL_checkstring(L, 2);
364+ return pushresult(L,
365+ (lua_toboolean(L,3) ? symlink : link)(oldpath, newpath), NULL);
366+}
367+
368+
369+static int Preadlink(lua_State *L) /** readlink(path) */
370+{
371+ char b[PATH_MAX];
372+ const char *path = luaL_checkstring(L, 1);
373+ int n = readlink(path, b, sizeof(b));
374+ if (n==-1) return pusherror(L, path);
375+ lua_pushlstring(L, b, n);
376+ return 1;
377+}
378+
379+
380+static int Paccess(lua_State *L) /** access(path,[mode]) */
381+{
382+ int mode=F_OK;
383+ const char *path=luaL_checkstring(L, 1);
384+ const char *s;
385+ for (s=luaL_optstring(L, 2, "f"); *s!=0 ; s++)
386+ switch (*s)
387+ {
388+ case ' ': break;
389+ case 'r': mode |= R_OK; break;
390+ case 'w': mode |= W_OK; break;
391+ case 'x': mode |= X_OK; break;
392+ case 'f': mode |= F_OK; break;
393+ default: badoption(L, 2, "mode", *s); break;
394+ }
395+ return pushresult(L, access(path, mode), path);
396+}
397+
398+
399+static int myfclose (lua_State *L) {
400+ FILE **p = (FILE **)lua_touserdata(L, 1);
401+ int rc = fclose(*p);
402+ if (rc == 0) *p = NULL;
403+ return pushresult(L, rc, NULL);
404+}
405+
406+static int pushfile (lua_State *L, int id, const char *mode) {
407+ FILE **f = (FILE **)lua_newuserdata(L, sizeof(FILE *));
408+ *f = NULL;
409+ luaL_getmetatable(L, LUA_FILEHANDLE);
410+ lua_setmetatable(L, -2);
411+ lua_getfield(L, LUA_REGISTRYINDEX, "POSIX_PIPEFILE");
412+ if (lua_isnil(L, -1)) {
413+ lua_pop(L, 1);
414+ lua_newtable(L);
415+ lua_pushvalue(L, -1);
416+ lua_pushcfunction(L, myfclose);
417+ lua_setfield(L, -2, "__close");
418+ lua_setfield(L, LUA_REGISTRYINDEX, "POSIX_PIPEFILE");
419+ }
420+ lua_setfenv(L, -2);
421+ *f = fdopen(id, mode);
422+ return (*f != NULL);
423+}
424+
425+static int Ppipe(lua_State *L) /** pipe() */
426+{
427+ int fd[2];
428+ if (pipe(fd)==-1) return pusherror(L, NULL);
429+ if (!pushfile(L, fd[0], "r") || !pushfile(L, fd[1], "w"))
430+ return pusherror(L, "pipe");
431+ return 2;
432+}
433+
434+
435+static int Pfileno(lua_State *L) /** fileno(filehandle) */
436+{
437+ FILE *f = *(FILE**) luaL_checkudata(L, 1, LUA_FILEHANDLE);
438+ return pushresult(L, fileno(f), NULL);
439+}
440+
441+
442+static int Pfdopen(lua_State *L) /** fdopen(fd, mode) */
443+{
444+ int fd = luaL_checkint(L, 1);
445+ const char *mode = luaL_checkstring(L, 2);
446+ if (!pushfile(L, fd, mode))
447+ return pusherror(L, "fdpoen");
448+ return 1;
449+}
450+
451+
452+/* helper func for Pdup */
453+static const char *filemode(int fd)
454+{
455+ const char *m;
456+ int mode = fcntl(fd, F_GETFL);
457+ if (mode < 0)
458+ return NULL;
459+ switch (mode & O_ACCMODE) {
460+ case O_RDONLY: m = "r"; break;
461+ case O_WRONLY: m = "w"; break;
462+ default: m = "rw"; break;
463+ }
464+ return m;
465+}
466+
467+static int Pdup(lua_State *L) /** dup(old,[new]) */
468+{
469+ FILE **oldf = (FILE**)luaL_checkudata(L, 1, LUA_FILEHANDLE);
470+ FILE **newf = (FILE **)lua_touserdata(L, 2);
471+ int fd;
472+ const char *msg = "dup2";
473+ fflush(*newf);
474+ if (newf == NULL) {
475+ fd = dup(fileno(*oldf));
476+ msg = "dup";
477+ } else {
478+ fflush(*newf);
479+ fd = dup2(fileno(*oldf), fileno(*newf));
480+ }
481+
482+ if ((fd < 0) || !pushfile(L, fd, filemode(fd)))
483+ return pusherror(L, msg);
484+ return 1;
485+}
486+
487+
488+static int Pmkfifo(lua_State *L) /** mkfifo(path) */
489+{
490+ const char *path = luaL_checkstring(L, 1);
491+ return pushresult(L, mkfifo(path, 0777), path);
492+}
493+
494+
495+static int runexec(lua_State *L, int use_shell)
496+{
497+ const char *path = luaL_checkstring(L, 1);
498+ int i,n=lua_gettop(L);
499+ char **argv = lua_newuserdata(L,(n+1)*sizeof(char*));
500+ argv[0] = (char*)path;
501+ for (i=1; i<n; i++) argv[i] = (char*)luaL_checkstring(L, i+1);
502+ argv[n] = NULL;
503+ if (use_shell) {
504+ execvp(path, argv);
505+ } else {
506+ execv(path, argv);
507+ }
508+ return pusherror(L, path);
509+}
510+
511+
512+static int Pexec(lua_State *L) /** exec(path,[args]) */
513+{
514+ return runexec(L, 0);
515+}
516+
517+
518+static int Pexecp(lua_State *L) /** execp(path,[args]) */
519+{
520+ return runexec(L, 1);
521+}
522+
523+
524+static int Pfork(lua_State *L) /** fork() */
525+{
526+ return pushresult(L, fork(), NULL);
527+}
528+
529+/* from http://lua-users.org/lists/lua-l/2007-11/msg00346.html */
530+static int Ppoll(lua_State *L) /** poll(filehandle, timeout) */
531+{
532+ struct pollfd fds;
533+ FILE* file = *(FILE**)luaL_checkudata(L,1,LUA_FILEHANDLE);
534+ int timeout = luaL_checkint(L,2);
535+ fds.fd = fileno(file);
536+ fds.events = POLLIN;
537+ return pushresult(L, poll(&fds,1,timeout), NULL);
538+}
539+
540+static int Pwait(lua_State *L) /** wait([pid]) */
541+{
542+ int status;
543+ pid_t pid = luaL_optint(L, 1, -1);
544+ pid = waitpid(pid, &status, 0);
545+ if (pid == -1) return pusherror(L, NULL);
546+ lua_pushinteger(L, pid);
547+ if (WIFEXITED(status))
548+ {
549+ lua_pushliteral(L,"exited");
550+ lua_pushinteger(L, WEXITSTATUS(status));
551+ return 3;
552+ }
553+ else if (WIFSIGNALED(status))
554+ {
555+ lua_pushliteral(L,"killed");
556+ lua_pushinteger(L, WTERMSIG(status));
557+ return 3;
558+ }
559+ else if (WIFSTOPPED(status))
560+ {
561+ lua_pushliteral(L,"stopped");
562+ lua_pushinteger(L, WSTOPSIG(status));
563+ return 3;
564+ }
565+ return 1;
566+}
567+
568+
569+static int Pkill(lua_State *L) /** kill(pid,[sig]) */
570+{
571+ pid_t pid = luaL_checkint(L, 1);
572+ int sig = luaL_optint(L, 2, SIGTERM);
573+ return pushresult(L, kill(pid, sig), NULL);
574+}
575+
576+static int Psetpid(lua_State *L) /** setpid(option,...) */
577+{
578+ const char *what=luaL_checkstring(L, 1);
579+ switch (*what)
580+ {
581+ case 'U':
582+ return pushresult(L, seteuid(mygetuid(L, 2)), NULL);
583+ case 'u':
584+ return pushresult(L, setuid(mygetuid(L, 2)), NULL);
585+ case 'G':
586+ return pushresult(L, setegid(mygetgid(L, 2)), NULL);
587+ case 'g':
588+ return pushresult(L, setgid(mygetgid(L, 2)), NULL);
589+ case 's':
590+ return pushresult(L, setsid(), NULL);
591+ case 'p':
592+ {
593+ pid_t pid = luaL_checkint(L, 2);
594+ pid_t pgid = luaL_checkint(L, 3);
595+ return pushresult(L, setpgid(pid,pgid), NULL);
596+ }
597+ default:
598+ badoption(L, 2, "id", *what);
599+ return 0;
600+ }
601+}
602+
603+
604+static int Psleep(lua_State *L) /** sleep(seconds) */
605+{
606+ unsigned int seconds = luaL_checkint(L, 1);
607+ lua_pushinteger(L, sleep(seconds));
608+ return 1;
609+}
610+
611+
612+static int Psetenv(lua_State *L) /** setenv(name,value,[over]) */
613+{
614+ const char *name=luaL_checkstring(L, 1);
615+ const char *value=luaL_optstring(L, 2, NULL);
616+ if (value==NULL)
617+ {
618+ unsetenv(name);
619+ return pushresult(L, 0, NULL);
620+ }
621+ else
622+ {
623+ int overwrite=lua_isnoneornil(L, 3) || lua_toboolean(L, 3);
624+ return pushresult(L, setenv(name,value,overwrite), NULL);
625+ }
626+}
627+
628+
629+static int Pgetenv(lua_State *L) /** getenv([name]) */
630+{
631+ if (lua_isnone(L, 1))
632+ {
633+ extern char **environ;
634+ char **e;
635+ lua_newtable(L);
636+ for (e=environ; *e!=NULL; e++)
637+ {
638+ char *s=*e;
639+ char *eq=strchr(s, '=');
640+ if (eq==NULL) /* will this ever happen? */
641+ {
642+ lua_pushstring(L,s);
643+ lua_pushboolean(L,1);
644+ }
645+ else
646+ {
647+ lua_pushlstring(L,s,eq-s);
648+ lua_pushstring(L,eq+1);
649+ }
650+ lua_settable(L,-3);
651+ }
652+ }
653+ else
654+ lua_pushstring(L, getenv(luaL_checkstring(L, 1)));
655+ return 1;
656+}
657+
658+static int Pumask(lua_State *L) /** umask([mode]) */
659+{/* <!LR> from old lposix-5.0 version */
660+ char m[10];
661+ mode_t mode;
662+ umask(mode=umask(0));
663+ mode=(~mode)&0777;
664+ if (!lua_isnone(L, 1))
665+ {
666+ if (mode_munch(&mode, luaL_checkstring(L, 1)))
667+ {
668+ lua_pushnil(L);
669+ return 1;
670+ }
671+ mode&=0777;
672+ umask(~mode);
673+ }
674+ modechopper(mode, m);
675+ lua_pushstring(L, m);
676+ return 1;
677+}
678+
679+
680+static int Pchmod(lua_State *L) /** chmod(path,mode) */
681+{
682+ mode_t mode;
683+ struct stat s;
684+ const char *path = luaL_checkstring(L, 1);
685+ const char *modestr = luaL_checkstring(L, 2);
686+ if (stat(path, &s)) return pusherror(L, path);
687+ mode = s.st_mode;
688+ if (mode_munch(&mode, modestr)) luaL_argerror(L, 2, "bad mode");
689+ return pushresult(L, chmod(path, mode), path);
690+}
691+
692+
693+static int Pchown(lua_State *L) /** chown(path,uid,gid) */
694+{
695+ const char *path = luaL_checkstring(L, 1);
696+ uid_t uid = mygetuid(L, 2);
697+ gid_t gid = mygetgid(L, 3);
698+ return pushresult(L, chown(path, uid, gid), path);
699+}
700+
701+
702+static int Putime(lua_State *L) /** utime(path,[mtime,atime]) */
703+{
704+ struct utimbuf times;
705+ time_t currtime = time(NULL);
706+ const char *path = luaL_checkstring(L, 1);
707+ times.modtime = luaL_optnumber(L, 2, currtime);
708+ times.actime = luaL_optnumber(L, 3, currtime);
709+ return pushresult(L, utime(path, &times), path);
710+}
711+
712+
713+static void FgetID(lua_State *L, int i, const void *data)
714+{
715+ switch (i)
716+ {
717+ case 0: lua_pushinteger(L, getegid()); break;
718+ case 1: lua_pushinteger(L, geteuid()); break;
719+ case 2: lua_pushinteger(L, getgid()); break;
720+ case 3: lua_pushinteger(L, getuid()); break;
721+ case 4: lua_pushinteger(L, getpgrp()); break;
722+ case 5: lua_pushinteger(L, getpid()); break;
723+ case 6: lua_pushinteger(L, getppid()); break;
724+ }
725+}
726+
727+static const char *const SgetID[] =
728+{
729+ "egid", "euid", "gid", "uid", "pgrp", "pid", "ppid", NULL
730+};
731+
732+static int Pgetpid(lua_State *L) /** getpid([options]) */
733+{
734+ return doselection(L, 1, SgetID, FgetID, NULL);
735+}
736+
737+
738+static int Phostid(lua_State *L) /** hostid() */
739+{
740+ char b[32];
741+ sprintf(b,"%ld",gethostid());
742+ lua_pushstring(L, b);
743+ return 1;
744+}
745+
746+
747+static int Pttyname(lua_State *L) /** ttyname([fd]) */
748+{
749+ int fd=luaL_optint(L, 1, 0);
750+ lua_pushstring(L, ttyname(fd));
751+ return 1;
752+}
753+
754+
755+static int Pctermid(lua_State *L) /** ctermid() */
756+{
757+ char b[L_ctermid];
758+ lua_pushstring(L, ctermid(b));
759+ return 1;
760+}
761+
762+
763+static int Pgetlogin(lua_State *L) /** getlogin() */
764+{
765+ lua_pushstring(L, getlogin());
766+ return 1;
767+}
768+
769+
770+static void Fgetpasswd(lua_State *L, int i, const void *data)
771+{
772+ const struct passwd *p=data;
773+ switch (i)
774+ {
775+ case 0: lua_pushstring(L, p->pw_name); break;
776+ case 1: lua_pushinteger(L, p->pw_uid); break;
777+ case 2: lua_pushinteger(L, p->pw_gid); break;
778+ case 3: lua_pushstring(L, p->pw_dir); break;
779+ case 4: lua_pushstring(L, p->pw_shell); break;
780+/* not strictly POSIX */
781+ case 5: lua_pushstring(L, p->pw_gecos); break;
782+ case 6: lua_pushstring(L, p->pw_passwd); break;
783+ }
784+}
785+
786+static const char *const Sgetpasswd[] =
787+{
788+ "name", "uid", "gid", "dir", "shell", "gecos", "passwd", NULL
789+};
790+
791+
792+static int Pgetpasswd(lua_State *L) /** getpasswd(name|id,[sel]) */
793+{
794+ struct passwd *p=NULL;
795+ if (lua_isnoneornil(L, 1))
796+ p = getpwuid(geteuid());
797+ else if (lua_isnumber(L, 1))
798+ p = getpwuid((uid_t)lua_tonumber(L, 1));
799+ else if (lua_isstring(L, 1))
800+ p = getpwnam(lua_tostring(L, 1));
801+ else
802+ luaL_typerror(L, 1, "string or number");
803+ if (p==NULL)
804+ lua_pushnil(L);
805+ else
806+ return doselection(L, 2, Sgetpasswd, Fgetpasswd, p);
807+ return 1;
808+}
809+
810+
811+static int Pgetgroup(lua_State *L) /** getgroup(name|id) */
812+{
813+ struct group *g=NULL;
814+ if (lua_isnumber(L, 1))
815+ g = getgrgid((gid_t)lua_tonumber(L, 1));
816+ else if (lua_isstring(L, 1))
817+ g = getgrnam(lua_tostring(L, 1));
818+ else
819+ luaL_typerror(L, 1, "string or number");
820+ if (g==NULL)
821+ lua_pushnil(L);
822+ else
823+ {
824+ int i;
825+ lua_newtable(L);
826+ lua_pushliteral(L, "name");
827+ lua_pushstring(L, g->gr_name);
828+ lua_settable(L, -3);
829+ lua_pushliteral(L, "gid");
830+ lua_pushinteger(L, g->gr_gid);
831+ lua_settable(L, -3);
832+ for (i=0; g->gr_mem[i]!=NULL; i++)
833+ {
834+ lua_pushstring(L, g->gr_mem[i]);
835+ lua_rawseti(L, -2, i);
836+ }
837+ }
838+ return 1;
839+}
840+
841+
842+struct mytimes
843+{
844+ struct tms t;
845+ clock_t elapsed;
846+};
847+
848+/* #define pushtime(L,x) lua_pushnumber(L,((lua_Number)x)/CLOCKS_PER_SEC) */
849+#define pushtime(L,x) lua_pushnumber(L, ((lua_Number)x)/clk_tck)
850+
851+static void Ftimes(lua_State *L, int i, const void *data)
852+{
853+ static long clk_tck = 0;
854+ const struct mytimes *t=data;
855+
856+ if( !clk_tck){ clk_tck= sysconf(_SC_CLK_TCK);}
857+ switch (i)
858+ {
859+ case 0: pushtime(L, t->t.tms_utime); break;
860+ case 1: pushtime(L, t->t.tms_stime); break;
861+ case 2: pushtime(L, t->t.tms_cutime); break;
862+ case 3: pushtime(L, t->t.tms_cstime); break;
863+ case 4: pushtime(L, t->elapsed); break;
864+ }
865+}
866+
867+static const char *const Stimes[] =
868+{
869+ "utime", "stime", "cutime", "cstime", "elapsed", NULL
870+};
871+
872+static int Ptimes(lua_State *L) /** times([options]) */
873+{
874+ struct mytimes t;
875+ t.elapsed = times(&t.t);
876+ return doselection(L, 1, Stimes, Ftimes, &t);
877+}
878+
879+
880+static const char *filetype(mode_t m)
881+{
882+ if (S_ISREG(m)) return "regular";
883+ else if (S_ISLNK(m)) return "link";
884+ else if (S_ISDIR(m)) return "directory";
885+ else if (S_ISCHR(m)) return "character device";
886+ else if (S_ISBLK(m)) return "block device";
887+ else if (S_ISFIFO(m)) return "fifo";
888+ else if (S_ISSOCK(m)) return "socket";
889+ else return "?";
890+}
891+
892+static void Fstat(lua_State *L, int i, const void *data)
893+{
894+ const struct stat *s=data;
895+ switch (i)
896+ {
897+ case 0: pushmode(L, s->st_mode); break;
898+ case 1: lua_pushinteger(L, s->st_ino); break;
899+ case 2: lua_pushinteger(L, s->st_dev); break;
900+ case 3: lua_pushinteger(L, s->st_nlink); break;
901+ case 4: lua_pushinteger(L, s->st_uid); break;
902+ case 5: lua_pushinteger(L, s->st_gid); break;
903+ case 6: lua_pushinteger(L, s->st_size); break;
904+ case 7: lua_pushinteger(L, s->st_atime); break;
905+ case 8: lua_pushinteger(L, s->st_mtime); break;
906+ case 9: lua_pushinteger(L, s->st_ctime); break;
907+ case 10:lua_pushstring(L, filetype(s->st_mode)); break;
908+ }
909+}
910+
911+static const char *const Sstat[] =
912+{
913+ "mode", "ino", "dev", "nlink", "uid", "gid",
914+ "size", "atime", "mtime", "ctime", "type",
915+ NULL
916+};
917+
918+static int Pstat(lua_State *L) /** stat(path,[options]) */
919+{
920+ struct stat s;
921+ const char *path=luaL_checkstring(L, 1);
922+ if (lstat(path,&s)==-1) return pusherror(L, path);
923+ return doselection(L, 2, Sstat, Fstat, &s);
924+}
925+
926+
927+static int Puname(lua_State *L) /** uname([string]) */
928+{
929+ struct utsname u;
930+ luaL_Buffer b;
931+ const char *s;
932+ if (uname(&u)==-1) return pusherror(L, NULL);
933+ luaL_buffinit(L, &b);
934+ for (s=luaL_optstring(L, 1, "%s %n %r %v %m"); *s; s++)
935+ if (*s!='%')
936+ luaL_putchar(&b, *s);
937+ else switch (*++s)
938+ {
939+ case '%': luaL_putchar(&b, *s); break;
940+ case 'm': luaL_addstring(&b,u.machine); break;
941+ case 'n': luaL_addstring(&b,u.nodename); break;
942+ case 'r': luaL_addstring(&b,u.release); break;
943+ case 's': luaL_addstring(&b,u.sysname); break;
944+ case 'v': luaL_addstring(&b,u.version); break;
945+ default: badoption(L, 2, "format", *s); break;
946+ }
947+ luaL_pushresult(&b);
948+ return 1;
949+}
950+
951+
952+static const int Kpathconf[] =
953+{
954+ _PC_LINK_MAX, _PC_MAX_CANON, _PC_MAX_INPUT, _PC_NAME_MAX, _PC_PATH_MAX,
955+ _PC_PIPE_BUF, _PC_CHOWN_RESTRICTED, _PC_NO_TRUNC, _PC_VDISABLE,
956+ -1
957+};
958+
959+static void Fpathconf(lua_State *L, int i, const void *data)
960+{
961+ const char *path=data;
962+ lua_pushinteger(L, pathconf(path, Kpathconf[i]));
963+}
964+
965+static const char *const Spathconf[] =
966+{
967+ "link_max", "max_canon", "max_input", "name_max", "path_max",
968+ "pipe_buf", "chown_restricted", "no_trunc", "vdisable",
969+ NULL
970+};
971+
972+static int Ppathconf(lua_State *L) /** pathconf([path,options]) */
973+{
974+ const char *path = luaL_optstring(L, 1, ".");
975+ return doselection(L, 2, Spathconf, Fpathconf, path);
976+}
977+
978+
979+static const int Ksysconf[] =
980+{
981+ _SC_ARG_MAX, _SC_CHILD_MAX, _SC_CLK_TCK, _SC_NGROUPS_MAX, _SC_STREAM_MAX,
982+ _SC_TZNAME_MAX, _SC_OPEN_MAX, _SC_JOB_CONTROL, _SC_SAVED_IDS, _SC_VERSION,
983+ -1
984+};
985+
986+static void Fsysconf(lua_State *L, int i, const void *data)
987+{
988+ lua_pushinteger(L, sysconf(Ksysconf[i]));
989+}
990+
991+static const char *const Ssysconf[] =
992+{
993+ "arg_max", "child_max", "clk_tck", "ngroups_max", "stream_max",
994+ "tzname_max", "open_max", "job_control", "saved_ids", "version",
995+ NULL
996+};
997+
998+static int Psysconf(lua_State *L) /** sysconf([options]) */
999+{
1000+ return doselection(L, 1, Ssysconf, Fsysconf, NULL);
1001+}
1002+
1003+#if ENABLE_SYSLOG
1004+/* syslog funcs */
1005+static int Popenlog(lua_State *L) /** openlog(ident, [option], [facility]) */
1006+{
1007+ const char *ident = luaL_checkstring(L, 1);
1008+ int option = 0;
1009+ int facility = luaL_optint(L, 3, LOG_USER);
1010+ const char *s = luaL_optstring(L, 2, "");
1011+ while (*s) {
1012+ switch (*s) {
1013+ case ' ': break;
1014+ case 'c': option |= LOG_CONS; break;
1015+ case 'n': option |= LOG_NDELAY; break;
1016+ case 'e': option |= LOG_PERROR; break;
1017+ case 'p': option |= LOG_PID; break;
1018+ default: badoption(L, 2, "option", *s); break;
1019+ }
1020+ s++;
1021+ }
1022+ openlog(ident, option, facility);
1023+ return 0;
1024+}
1025+
1026+
1027+static int Psyslog(lua_State *L) /** syslog(priority, message) */
1028+{
1029+ int priority = luaL_checkint(L, 1);
1030+ const char *msg = luaL_checkstring(L, 2);
1031+ syslog(priority, "%s", msg);
1032+ return 0;
1033+}
1034+
1035+
1036+static int Pcloselog(lua_State *L) /** closelog() */
1037+{
1038+ closelog();
1039+ return 0;
1040+}
1041+#endif
1042+
1043+/*
1044+ * XXX: GNU and BSD handle the forward declaration of crypt() in different
1045+ * and annoying ways (especially GNU). Declare it here just to make sure
1046+ * that it's there
1047+ */
1048+char *crypt(const char *, const char *);
1049+
1050+static int Pcrypt(lua_State *L)
1051+{
1052+ const char *str, *salt;
1053+ char *res;
1054+
1055+ str = luaL_checkstring(L, 1);
1056+ salt = luaL_checkstring(L, 2);
1057+ if (strlen(salt) < 2)
1058+ luaL_error(L, "not enough salt");
1059+
1060+ res = crypt(str, salt);
1061+ lua_pushstring(L, res);
1062+
1063+ return 1;
1064+}
1065+
1066+static const luaL_reg R[] =
1067+{
1068+ {"access", Paccess},
1069+ {"basename", Pbasename},
1070+ {"chdir", Pchdir},
1071+ {"chmod", Pchmod},
1072+ {"chown", Pchown},
1073+ {"crypt", Pcrypt},
1074+ {"ctermid", Pctermid},
1075+ {"dirname", Pdirname},
1076+ {"dir", Pdir},
1077+ {"dup", Pdup},
1078+ {"errno", Perrno},
1079+ {"exec", Pexec},
1080+ {"execp", Pexecp},
1081+ {"fdopen", Pfdopen},
1082+ {"fileno", Pfileno},
1083+ {"files", Pfiles},
1084+ {"fork", Pfork},
1085+ {"getcwd", Pgetcwd},
1086+ {"getenv", Pgetenv},
1087+ {"getgroup", Pgetgroup},
1088+ {"getlogin", Pgetlogin},
1089+ {"getpasswd", Pgetpasswd},
1090+ {"getpid", Pgetpid},
1091+ {"glob", Pglob},
1092+ {"hostid", Phostid},
1093+ {"kill", Pkill},
1094+ {"link", Plink},
1095+ {"mkdir", Pmkdir},
1096+ {"mkfifo", Pmkfifo},
1097+ {"pathconf", Ppathconf},
1098+ {"pipe", Ppipe},
1099+ {"readlink", Preadlink},
1100+ {"rmdir", Prmdir},
1101+ {"rpoll", Ppoll},
1102+ {"setenv", Psetenv},
1103+ {"setpid", Psetpid},
1104+ {"sleep", Psleep},
1105+ {"stat", Pstat},
1106+ {"sysconf", Psysconf},
1107+ {"times", Ptimes},
1108+ {"ttyname", Pttyname},
1109+ {"unlink", Punlink},
1110+ {"umask", Pumask},
1111+ {"uname", Puname},
1112+ {"utime", Putime},
1113+ {"wait", Pwait},
1114+
1115+#if ENABLE_SYSLOG
1116+ {"openlog", Popenlog},
1117+ {"syslog", Psyslog},
1118+ {"closelog", Pcloselog},
1119+#endif
1120+
1121+ {NULL, NULL}
1122+};
1123+
1124+#define set_const(key, value) \
1125+ lua_pushliteral(L, key); \
1126+ lua_pushnumber(L, value); \
1127+ lua_settable(L, -3)
1128+
1129+LUALIB_API int luaopen_posix (lua_State *L)
1130+{
1131+ luaL_register(L,MYNAME,R);
1132+ lua_pushliteral(L,"version"); /** version */
1133+ lua_pushliteral(L,MYVERSION);
1134+ lua_settable(L,-3);
1135+
1136+#if ENABLE_SYSLOG
1137+ set_const("LOG_AUTH", LOG_AUTH);
1138+ set_const("LOG_AUTHPRIV", LOG_AUTHPRIV);
1139+ set_const("LOG_CRON", LOG_CRON);
1140+ set_const("LOG_DAEMON", LOG_DAEMON);
1141+ set_const("LOG_FTP", LOG_FTP);
1142+ set_const("LOG_KERN", LOG_KERN);
1143+ set_const("LOG_LOCAL0", LOG_LOCAL0);
1144+ set_const("LOG_LOCAL1", LOG_LOCAL1);
1145+ set_const("LOG_LOCAL2", LOG_LOCAL2);
1146+ set_const("LOG_LOCAL3", LOG_LOCAL3);
1147+ set_const("LOG_LOCAL4", LOG_LOCAL4);
1148+ set_const("LOG_LOCAL5", LOG_LOCAL5);
1149+ set_const("LOG_LOCAL6", LOG_LOCAL6);
1150+ set_const("LOG_LOCAL7", LOG_LOCAL7);
1151+ set_const("LOG_LPR", LOG_LPR);
1152+ set_const("LOG_MAIL", LOG_MAIL);
1153+ set_const("LOG_NEWS", LOG_NEWS);
1154+ set_const("LOG_SYSLOG", LOG_SYSLOG);
1155+ set_const("LOG_USER", LOG_USER);
1156+ set_const("LOG_UUCP", LOG_UUCP);
1157+
1158+ set_const("LOG_EMERG", LOG_EMERG);
1159+ set_const("LOG_ALERT", LOG_ALERT);
1160+ set_const("LOG_CRIT", LOG_CRIT);
1161+ set_const("LOG_ERR", LOG_ERR);
1162+ set_const("LOG_WARNING", LOG_WARNING);
1163+ set_const("LOG_NOTICE", LOG_NOTICE);
1164+ set_const("LOG_INFO", LOG_INFO);
1165+ set_const("LOG_DEBUG", LOG_DEBUG);
1166+#endif
1167+
1168+
1169+ return 1;
1170+}
1171+
1172+/*EOF*/
1173--- a/src/lualib.h
1174+++ b/src/lualib.h
1175@@ -39,6 +39,9 @@ LUALIB_API int (luaopen_debug) (lua_Stat
1176 #define LUA_LOADLIBNAME "package"
1177 LUALIB_API int (luaopen_package) (lua_State *L);
1178 
1179+#define LUA_POSIXLIBNAME "posix"
1180+LUALIB_API int (luaopen_posix) (lua_State *L);
1181+
1182 
1183 /* open all previous libraries */
1184 LUALIB_API void (luaL_openlibs) (lua_State *L);
1185--- /dev/null
1186+++ b/src/modemuncher.c
1187@@ -0,0 +1,261 @@
1188+/*
1189+ Mode Muncher -- modemuncher.c
1190+ 961110 Claudio Terra
1191+
1192+ munch vb
1193+ [ME monchen, perh. influenced by MF mangier to eat --more at MANGER]
1194+ :to chew with a crunching sound: eat with relish
1195+ :to chew food with a crunching sound: eat food with relish
1196+ --munch-er n
1197+
1198+ The NeXT Digital Edition of Webster's Ninth New Collegiate Dictionary
1199+ and Webster's Collegiate Thesaurus
1200+*/
1201+
1202+/* struct for rwx <-> POSIX constant lookup tables */
1203+struct modeLookup
1204+{
1205+ char rwx;
1206+ mode_t bits;
1207+};
1208+
1209+typedef struct modeLookup modeLookup;
1210+
1211+static modeLookup modesel[] =
1212+{
1213+ /* RWX char Posix Constant */
1214+ {'r', S_IRUSR},
1215+ {'w', S_IWUSR},
1216+ {'x', S_IXUSR},
1217+
1218+ {'r', S_IRGRP},
1219+ {'w', S_IWGRP},
1220+ {'x', S_IXGRP},
1221+
1222+ {'r', S_IROTH},
1223+ {'w', S_IWOTH},
1224+ {'x', S_IXOTH},
1225+ {0, (mode_t)-1} /* do not delete this line */
1226+};
1227+
1228+
1229+
1230+static int rwxrwxrwx(mode_t *mode, const char *p)
1231+{
1232+ int count;
1233+ mode_t tmp_mode = *mode;
1234+
1235+ tmp_mode &= ~(S_ISUID | S_ISGID); /* turn off suid and sgid flags */
1236+ for (count=0; count<9; count ++)
1237+ {
1238+ if (*p == modesel[count].rwx) tmp_mode |= modesel[count].bits; /* set a bit */
1239+ else if (*p == '-') tmp_mode &= ~modesel[count].bits; /* clear a bit */
1240+ else if (*p=='s') switch(count)
1241+ {
1242+ case 2: /* turn on suid flag */
1243+ tmp_mode |= S_ISUID | S_IXUSR;
1244+ break;
1245+
1246+ case 5: /* turn on sgid flag */
1247+ tmp_mode |= S_ISGID | S_IXGRP;
1248+ break;
1249+
1250+ default:
1251+ return -4; /* failed! -- bad rwxrwxrwx mode change */
1252+ break;
1253+ }
1254+ p++;
1255+ }
1256+ *mode = tmp_mode;
1257+ return 0;
1258+}
1259+
1260+static void modechopper(mode_t mode, char *p)
1261+{
1262+ /* requires char p[10] */
1263+ int count;
1264+ char *pp;
1265+
1266+ pp=p;
1267+
1268+ for (count=0; count<9; count ++)
1269+ {
1270+ if (mode & modesel[count].bits) *p = modesel[count].rwx;
1271+ else *p='-';
1272+
1273+ p++;
1274+ }
1275+ *p=0; /* to finish the string */
1276+
1277+ /* dealing with suid and sgid flags */
1278+ if (mode & S_ISUID) pp[2] = (mode & S_IXUSR) ? 's' : 'S';
1279+ if (mode & S_ISGID) pp[5] = (mode & S_IXGRP) ? 's' : 'S';
1280+
1281+}
1282+
1283+static int mode_munch(mode_t *mode, const char* p)
1284+{
1285+
1286+ char op=0;
1287+ mode_t affected_bits, ch_mode;
1288+ int doneFlag = 0;
1289+#ifdef DEBUG
1290+char tmp[10];
1291+#endif
1292+
1293+#ifdef DEBUG
1294+modechopper(*mode, tmp);
1295+printf("modemuncher: got base mode = %s\n", tmp);
1296+#endif
1297+
1298+ while (!doneFlag)
1299+ {
1300+ /* step 0 -- clear temporary variables */
1301+ affected_bits=0;
1302+ ch_mode=0;
1303+
1304+ /* step 1 -- who's affected? */
1305+
1306+#ifdef DEBUG
1307+printf("modemuncher step 1\n");
1308+#endif
1309+
1310+ /* mode string given in rwxrwxrwx format */
1311+ if (*p== 'r' || *p == '-') return rwxrwxrwx(mode, p);
1312+
1313+ /* mode string given in ugoa+-=rwx format */
1314+ for ( ; ; p++)
1315+ switch (*p)
1316+ {
1317+ case 'u':
1318+ affected_bits |= 04700;
1319+ break;
1320+
1321+ case 'g':
1322+ affected_bits |= 02070;
1323+ break;
1324+
1325+ case 'o':
1326+ affected_bits |= 01007;
1327+ break;
1328+
1329+ case 'a':
1330+ affected_bits |= 07777;
1331+ break;
1332+
1333+ /* ignore spaces */
1334+ case ' ':
1335+ break;
1336+
1337+
1338+ default:
1339+ goto no_more_affected;
1340+ }
1341+
1342+ no_more_affected:
1343+ /* If none specified, affect all bits. */
1344+ if (affected_bits == 0) affected_bits = 07777;
1345+
1346+ /* step 2 -- how is it changed? */
1347+
1348+#ifdef DEBUG
1349+printf("modemuncher step 2 (*p='%c')\n", *p);
1350+#endif
1351+
1352+ switch (*p)
1353+ {
1354+ case '+':
1355+ case '-':
1356+ case '=':
1357+ op = *p;
1358+ break;
1359+
1360+ /* ignore spaces */
1361+ case ' ':
1362+ break;
1363+
1364+ default:
1365+ return -1; /* failed! -- bad operator */
1366+ }
1367+
1368+
1369+ /* step 3 -- what are the changes? */
1370+
1371+#ifdef DEBUG
1372+printf("modemuncher step 3\n");
1373+#endif
1374+
1375+ for (p++ ; *p!=0 ; p++)
1376+ switch (*p)
1377+ {
1378+ case 'r':
1379+ ch_mode |= 00444;
1380+ break;
1381+
1382+ case 'w':
1383+ ch_mode |= 00222;
1384+ break;
1385+
1386+ case 'x':
1387+ ch_mode |= 00111;
1388+ break;
1389+
1390+ case 's':
1391+ /* Set the setuid/gid bits if `u' or `g' is selected. */
1392+ ch_mode |= 06000;
1393+ break;
1394+
1395+ /* ignore spaces */
1396+ case ' ':
1397+ break;
1398+
1399+ default:
1400+ goto specs_done;
1401+ }
1402+
1403+ specs_done:
1404+ /* step 4 -- apply the changes */
1405+
1406+#ifdef DEBUG
1407+ printf("modemuncher step 4\n");
1408+#endif
1409+ if (*p != ',') doneFlag = 1;
1410+ if (*p != 0 && *p != ' ' && *p != ',')
1411+ {
1412+
1413+#ifdef DEBUG
1414+printf("modemuncher: comma error!\n");
1415+printf("modemuncher: doneflag = %u\n", doneFlag);
1416+#endif
1417+ return -2; /* failed! -- bad mode change */
1418+
1419+ }
1420+ p++;
1421+ /*if (!ch_mode) return -2;*/ /* failed! -- bad mode change */
1422+ if (ch_mode) switch (op)
1423+ {
1424+ case '+':
1425+ *mode = *mode |= ch_mode & affected_bits;
1426+ break;
1427+
1428+ case '-':
1429+ *mode = *mode &= ~(ch_mode & affected_bits);
1430+ break;
1431+
1432+ case '=':
1433+ *mode = ch_mode & affected_bits;
1434+ break;
1435+
1436+ default:
1437+ return -3; /* failed! -- unknown error */
1438+ }
1439+ }
1440+#ifdef DEBUG
1441+modechopper(*mode, tmp);
1442+printf("modemuncher: returning mode = %s\n", tmp);
1443+#endif
1444+
1445+ return 0; /* successful call */
1446+}
1447+
1448+
1449

Archive Download this file



interactive