aboutsummaryrefslogtreecommitdiff
path: root/riemann.fmi.uni-sofia.bg/ngetty/ngetty-1.1/ngetty-helper.c
diff options
context:
space:
mode:
authorKlaatu Sverige <[email protected]>2015-08-05 21:31:21 +0000
committerKlaatu Sverige <[email protected]>2015-08-05 21:31:21 +0000
commit86f0721bd904d8163c5f8f2472b78169146cc67d (patch)
treecf9e61bd495c73ece45b96242e6f575af228d01d /riemann.fmi.uni-sofia.bg/ngetty/ngetty-1.1/ngetty-helper.c
parent75a501d32dff3c1c1ee9a2a3dc6d5b704cc7c6d1 (diff)
added website data, because it had heaps of good tutorials and info
Diffstat (limited to 'riemann.fmi.uni-sofia.bg/ngetty/ngetty-1.1/ngetty-helper.c')
-rw-r--r--riemann.fmi.uni-sofia.bg/ngetty/ngetty-1.1/ngetty-helper.c335
1 files changed, 335 insertions, 0 deletions
diff --git a/riemann.fmi.uni-sofia.bg/ngetty/ngetty-1.1/ngetty-helper.c b/riemann.fmi.uni-sofia.bg/ngetty/ngetty-1.1/ngetty-helper.c
new file mode 100644
index 0000000..a368b7a
--- /dev/null
+++ b/riemann.fmi.uni-sofia.bg/ngetty/ngetty-1.1/ngetty-helper.c
@@ -0,0 +1,335 @@
+#define _GNU_SOURCE
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <alloca.h>
+#include <errno.h>
+#include <termios.h>
+#include <sys/utsname.h>
+#include <sys/ioctl.h>
+#include <sys/param.h>
+#include "lib.h"
+#include "opts_defs.h"
+
+/* most of the functions here (like str_copy, fmt_ulong)
+ have manual pages in libowfat; http://www.fefe.de/
+ see also opts_defs.h for o[Oxxx]; man ngetty */
+
+/* see out_put.c; man buffer */
+#define outs(X) out_puts(X)
+#define GO_out "go out!"
+
+static struct utsname uts;
+static struct stat st;
+static char *tty, *o_opt, o_endchar;
+char **Oo = o; /* see opts_defs.h */
+
+static void tty_flush() { ioctl(0, TCFLSH, TCIFLUSH); }
+
+/* Format of o[Oprint]: ab:cq:09:AZ:...; man ngetty
+ return -1 if 'ch' does not belongs to the set o[Oprint]; 0 success */
+static int char_allow(unsigned char ch) {
+ unsigned char c0, c1, *x = (unsigned char *)o[Oprint];
+ again:
+ c0 = x[0]; if (!c0) return -1;
+ c1 = x[1]; if (!c1) return -1;
+ if (c0 <= ch && ch <= c1) return 0;
+ if (x[2] == ':') { x += 3; goto again; }
+ return -1;
+}
+
+/* print maximal 'len' chars from 's'; see strncpy, snprintf, printf */
+static void out_max(char *s, unsigned int len) {
+ char c = 0;
+ if (s == uts.nodename && !o[Olonghostname]) c = '.';
+ while (len && *s && *s != c) {
+ out_char(*s); ++s; --len;
+ }
+}
+
+#define Out_MAX(X) x=X; len=sizeof(X); goto system
+
+/* print string with escapes; man ngetty; man issue */
+static void output_special_char(char *s, int len) {
+ char *last = s + len;
+ while (s < last) {
+ char *x, c;
+ if (*s != '\\') { out_char(*s); ++s; continue; }
+ if (++s == last) return;
+
+ c = *s++;
+ switch (c) {
+ case 's': Out_MAX(uts.sysname);
+ case 'n': Out_MAX(uts.nodename);
+ case 'r': Out_MAX(uts.release);
+ case 'v': Out_MAX(uts.version);
+ case 'm': Out_MAX(uts.machine);
+ case 'o': Out_MAX(uts.domainname);
+ system:
+ out_max(x,len); break;
+ case 'l':
+ outs(tty); break;
+#ifndef DONT_NEED_ESC_TIME
+ case 't':
+ x = "H:M:S"; goto do_time;
+ case 'd':
+ x = (o[Odatestring]) ? "a b d Y" : "Y-m-d";
+ do_time:
+ fmt_time(x); break;
+#endif
+#ifndef DONT_NEED_ESC_USERS
+ case 'u':
+ case 'U':
+ {
+ char ubuf[8 + 3*sizeof(unsigned long)], *x = ubuf;
+ unsigned long usrs = utmp_users();
+ x += fmt_ulong(x, usrs);
+ if (c=='U') {
+ x += str_copynz(x, " users", 10);
+ if (usrs==1) --x;
+ }
+ *x = 0;
+ outs(ubuf);
+ }
+ break;
+#endif
+ default:
+ if (s+1 < last) {
+ unsigned char uch = (unsigned char)c-'0';
+ if (uch < 4) { /* XXX \0xy is not tested */
+ c = (uch<<6) | ((s[0]-'0')<<3) | (s[1]-'0');
+ s += 2;
+ }
+ }
+ out_char(c);
+ }
+ }
+}
+
+/* print string 's' with escapes; man ngetty */
+static void Out_sp_ch(char *s) { output_special_char(s, str_len(s)); }
+
+/* exception: print string 's' and exit with status 'i' */
+void error(char *s,int i) {
+ struct timespec ts = { 2, 500111222 };
+ Out_sp_ch("\nngetty-helper: \\d \\t \\l: ");
+ outs(s); out_char('\n'); out_flush();
+ nanosleep(&ts, 0);
+ tty_flush();
+ _exit(i);
+}
+
+/* print /etc/issue and login prompt; man issue */
+static void do_prompt() {
+ int fd,len;
+ char *s;
+ Out_sp_ch(o[Onewline]);
+ s = o[Oissuefile];
+ if (s[0] && (fd=open(s, O_RDONLY)) >= 0) {
+ if (GLOBAL_fstat_READ(fd,st,s, len,64000, 1)) _exit(1);
+ close(fd);
+ output_special_char(s, len);
+ }
+ Out_sp_ch(o[Ologinprompt]);
+ out_flush();
+}
+
+/* get login name in logname. max length = last-logname
+ man ngetty; options: login-buffer, timeout */
+static void get_logname(char *logname, char *last) {
+ char *c;
+ alarm(x_atoi(o[Otimeout]));
+ for (;;) {
+ for (c=logname;; c++) {
+ if (c == last)
+ error("login name too long",11);
+ if (read(0,c,1)<1) {
+ if (errno==EINTR || errno==EIO || errno==ENOENT)
+ _exit(0);
+ error("received strange error",9);
+ }
+ if (*c == '\n' || *c == '\r') {
+ *c=0;
+ break;
+ }
+ if (char_allow((unsigned char)*c))
+ error("bad character in login name",10);
+ } /* end read */
+ if (*logname == '-')
+ error("username may not start with a dash",13);
+ if (*logname) break;
+ do_prompt();
+ }
+ alarm(0);
+}
+
+/* parse string; store it in o[XXX]; see opts_defs.h; /etc/ngetty/Conf */
+static char *opt_get(char *s, int len) {
+ if (*o_opt == *s) {
+ char *x = o_opt;
+ if (!str_diffn(x,s,len) && x[len] == o_endchar) {
+ if (o[Odebug] && s != tty) {
+ outs(x - 1);
+ out_char('\n');
+ }
+ return x+len+1;
+ }
+ }
+ return 0;
+}
+
+/* return 1 if user is in s, otherwise 0;
+ Format of s: ,ab,uvw,MlqR, ... ,last */
+static char in_list(char *s, const char *user) {
+ char ch;
+ int len;
+ if (s==0 || *s==0 || user==0) return 0;
+ len = str_len(user);
+ ch = *s++;
+ again:
+ if (!str_diffn(s,user,len))
+ if (s[len]==ch || s[len]==0) return 1;
+ while (*s && *s != ch) s++;
+ if (*s++) goto again;
+ return 0;
+}
+
+/* set controlling tty */
+static void set_ctty() {
+ if (setsid() == -1 || ioctl(0, TIOCSCTTY, (void *)1))
+ error(GO_out, 111);
+}
+
+int main(int argc,char *argv[]) {
+ int fd,len;
+ char *s;
+ struct termios term;
+ if (argc < 2) _exit(100);
+
+ o[Oautologinfirst] = o[Onoclearfirst] = o[Oautologinname] = "";
+ o[Oissuefile] = "/etc/issue";
+ o[Ologinprog] = LOGIN;
+ o[Oprint] = "az:AZ:09:,.:__";
+ o[Otimeout] = "180";
+ o[Ologinprompt] = "\\n login: ";
+ o[Onewline] = "\n";
+ o[Oclear] = "\033c";
+#ifndef DONT_NEED_ESC_TIME
+ o[Omonths] = "JanFebMarAprMayJunJulAugSepOctNovDec";
+ o[Odays] = "SunMonTueWedThuFriSat";
+ o[Otz] = "/etc/localtime";
+#endif
+
+ tty = argv[1];
+ uname(&uts);
+ if (dup(0) !=1 || dup(0) !=2 || ioctl(0,TCGETS,&term)) error(GO_out, 100);
+ if (!str_diffn(tty, "/dev/", 5)) tty += 5;
+
+ if ((fd = open(NGETTY_HOME "/Conf", O_RDONLY)) >=0) {
+ char **aa=0, *q;
+ int tty_len = str_len(tty);
+ /* 40 bytes for Months or Days */
+ if (GLOBAL_fstat_READ(fd,st,s, len,64000, 40)) _exit(1);
+ close(fd);
+ if (st.st_uid || st.st_gid || (st.st_mode & 07177)) len = 0;
+ s[len]=0;
+
+ GLOBAL_split(aa,s,'\n', len);
+
+ for (; *aa; aa++) {
+ s=aa[0];
+ if (*s==0 || *s=='#' || *s=='\t' || *s==' ') continue;
+
+ o_endchar = '=';
+ if (*s=='=') o_opt = s+1;
+ else {
+ o_opt = s;
+ if (!(o_opt = opt_get(tty, tty_len))) continue;
+ }
+
+ for (len=0, q=(char *)P_opt; len < MAX_options; len++) {
+ int k = P_len[len];
+ if (len >= MAX_equal) o_endchar = 0;
+ if ((s = opt_get(q, k))) { o[len] = s; break; }
+ q += k;
+ }
+ }
+ }
+
+ if ((s=o[Onice])) nice(x_atoi(s));
+
+ if ((s=o[Oenviron])) {
+ char **ee=0, ch=*s++;
+ if (ch) GLOBAL_split(ee,s,ch, len);
+ environ=ee;
+ }
+
+ if (argc>2 && argv[2][0] == 'l') { /* get logname and execve() login */
+ char *loginargv[]={ o[Ologinprog], "--", 0, 0, 0 };
+ fork_and_exec(o[OshB]);
+
+ s = o[Oautologinfirst];
+ if (*s && !check_first(s,&st)) o[Oautologinname] = "";
+
+ s = o[Oautologinname];
+ if (*s) {
+ loginargv[1] = "-f";
+ loginargv[2] = s;
+ } else {
+ o[Oissuefile] = "";
+ if (!o[Onousername]) {
+ char *last, *buf = o[Ologinbuffer];
+ if (buf) last = buf + str_len(buf);
+ else { buf = alloca(41); last = buf + 40; }
+ loginargv[2] = buf;
+ get_logname(buf, last);
+ }
+ }
+
+ if (o[Oechooff]) {
+ term.c_lflag &= ~(ECHO|ISIG);
+ ioctl(0, TCSETS, &term);
+ }
+
+ if ((s=o[Ologinargv])) {
+ loginargv[1] = s; /* change '--' or '-f' with login-argv */
+ loginargv[3] = tty;
+ }
+
+ s = loginargv[2];
+ if (in_list(o[Odeny],s) ||
+ (o[Oallow] && in_list(o[Oallow],s)==0))
+ error("login is disabled",14);
+
+ out_flush();
+ tty_flush();
+ utmp_do(1,tty);
+
+ if ((s=o[Ochroot])) chroot(s);
+ if ((s=o[Ochdir])) chdir(s);
+ set_ctty();
+ execve(*loginargv, loginargv, environ);
+ } else { /* print /etc/issue and exit */
+ char *clear = o[Oclear];
+ tty_flush();
+
+ fork_and_exec(o[OshA]);
+ if ((s=o[Odelay])) {
+ struct timespec ts = { x_atoi(s), 100200300 };
+ nanosleep(&ts, 0);
+ }
+
+ s = o[Onoclearfirst];
+ if (*s && check_first(s,&st)) clear = "";
+
+ Out_sp_ch(clear);
+ utmp_do(0,tty);
+ do_prompt();
+
+#ifdef HAVE_SYSTEM_VHANGUP
+ if (!o[Onohangup]) { set_ctty(); vhangup(); }
+#endif
+ }
+ _exit(0);
+}