diff options
Diffstat (limited to 'riemann.fmi.uni-sofia.bg/ngetty/ngetty-1.1/ngetty-argv.c')
| -rw-r--r-- | riemann.fmi.uni-sofia.bg/ngetty/ngetty-1.1/ngetty-argv.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/riemann.fmi.uni-sofia.bg/ngetty/ngetty-1.1/ngetty-argv.c b/riemann.fmi.uni-sofia.bg/ngetty/ngetty-1.1/ngetty-argv.c new file mode 100644 index 0000000..a8b943d --- /dev/null +++ b/riemann.fmi.uni-sofia.bg/ngetty/ngetty-1.1/ngetty-argv.c @@ -0,0 +1,148 @@ +#include <unistd.h> +#include <fcntl.h> +#include <sys/types.h> +#include <time.h> +#include <alloca.h> +#include <grp.h> +#include <termios.h> +#include <sys/ioctl.h> +#include "lib.h" +#define UUU "unable to " + +void w(char *s) { write(2, s, str_len(s)); } +void e(char *x0, char *x1) + { w("\nngetty-argv: "); w(x0); w(x1); w("\n"); sleep(1); } +/* sleep is needed to see the erros. see the option clear also */ + +unsigned int expand_string(char *tmp, char *string, char *user, char *tty) { + char *s=string, *pos=tmp, *exp, ch, found_one = 0; + for (; (ch=*s); s++) { + if (ch == '%') { + found_one = 1; + ch = s[1]; + exp = user; + + switch (ch) { + case 'T': exp = tty; + case 'U': + pos += (tmp) ? str_copy(pos, exp) : str_len(exp); + ++s; + break; + case '%': /* %%U -> %U */ + ++s; + default: + ch = *s; + goto non_special; + } + } else { + non_special: + if (tmp) *pos = ch; + ++pos; + } + } + + if (found_one) { + if (tmp==0) return pos - tmp + 1; + else *pos = 0; + } + return 0; +} + +int main(int argc, char **argv) { + char **arg=0, **ee, **aa, *in=0, *s, ch; + char *user, *tty, flagsetsid=0, flagdaemon=0, flagtty=0, *flagpid=0; + unsigned long n; + uid_t uid=0; + gid_t gid=0; + + if (argc<2) { + usage: + e("usage:\n\tngetty-argv [Options][--]ArgvString [user [tty]]\n\n", + "\tArgvString:\t:/bin/sleep:hacker_sleep:39:other:args...\n" + "\tOptions:\t:-D:-S:-N:-C:-u123:-g59:-a45:-s3:-d/tmp:-r/var/tmp\n" + "\tOptions:\t:-e,HOME=/,TERM=linux:-p/var/run/ngetty.pid\n" + "\tExample:\t:-u106:-g506:-d/var/qmail:--:./bin/qmail-qread:queue\n"); + return 100; + } + + user =(argc>2) ? argv[2] : ""; + tty =(argc>3) ? argv[3] : ""; + + do { + n = expand_string(in, argv[1], user, tty); + if (n==0) break; + in = alloca(n); + } while (1); + if (in==0) in=argv[1]; + + ch = *in++; /* don't use '%' as split char */ + if (ch == 0 || *in == 0) goto usage; + GLOBAL_split_plus(arg,in,ch, n,5); + if (n < 2) goto usage; + + for (aa=arg; (s=*aa); aa++) { + if (*s != '-') break; + s += 2; + n=x_atoi(s); + switch (s[-1]) { + case 'e': + ee = 0; + ch = *s++; + if (ch) GLOBAL_split(ee,s,ch, n); + environ = ee; + break; + case 'D': flagdaemon=1; break; + case 'S': flagsetsid=1; break; + case 'N': flagtty=1; break; + case 'C': flagtty=2; break; + case 'p': if (*s) flagpid=s; break; + case 'g': gid = n; break; + case 'u': uid = n; break; + case 'a': alarm(n); break; + case 's': sleep(n); break; + case 'd': if (chdir(s)) { e(s, ": chdir error"); return 100; } break; + case 'r': if (chroot(s)) { e(s, ": chroot error"); return 100; } break; + case '-': aa++; goto do_it; + default: + e(s-2, " : unknown option"); + return 1; + } + } + + do_it: + if (flagdaemon) { + int pid; + while ((pid=fork()) <0) sleep(1); + if (pid) _exit(0); + } + + if (flagsetsid) setsid(); + if (flagtty==1) ioctl(0, TIOCNOTTY, (void *)1); + if (flagtty==2) ioctl(0, TIOCSCTTY, (void *)1); + + if (flagpid) { + int fd = open(flagpid, O_RDWR | O_TRUNC | O_CREAT, 0644); + if (fd>=0) { + char tmp[3*sizeof(unsigned long)]; + n=fmt_ulong(tmp, getpid()); + tmp[n] = '\n'; + write(fd, tmp, n+1); + close(fd); + } + } + + if (uid || gid) { + if (gid==0) gid = uid; + if (setgroups(1,&gid) || + setgid(gid) || + setuid(uid)) { e(UUU, "set uidgid"); return 100; } + } + + s = *aa++; + if (s==0 || *aa==0) return 0; + if (aa[0][0] == 0) aa[0] = s; + + execve(s, aa, environ); + e(s, ": exec error"); + return 127; +} |
