diff --git a/usr.sbin/cron/Makefile b/usr.sbin/cron/Makefile new file mode 100644 index 0000000..211d7bd --- /dev/null +++ b/usr.sbin/cron/Makefile @@ -0,0 +1,5 @@ +cron.root: cron.c + compile -p cron.c keep=cron + +cron: cron.root + link -p cron keep=cron diff --git a/usr.sbin/cron/README b/usr.sbin/cron/README new file mode 100644 index 0000000..b7cbd32 --- /dev/null +++ b/usr.sbin/cron/README @@ -0,0 +1,5 @@ +I converted cron to use syslog(). In my /etc/syslog.conf file, LOG_CRON +messages are configured to go in /var/log/cronlog. I modifed cron as a +demonstration of this. + +- Phillip Vandry diff --git a/usr.sbin/cron/cron.8 b/usr.sbin/cron/cron.8 new file mode 100644 index 0000000..ca36b3a --- /dev/null +++ b/usr.sbin/cron/cron.8 @@ -0,0 +1,48 @@ +CRON(8) UNIX Programmer's Manual CRON(8) + + + +NAME + cron - clock daemon + +SYNOPSIS + /usr/sbin/cron + +DESCRIPTION + Cron executes commands at specified dates and times accord- + ing to the instructions in the file /etc/crontab (if it exists). + Since cron never exits, it should only be executed once. This + is best done by running cron from the initialization process + through the file /etc/inittab; see init(8). + + The crontab file consists of lines of seven fields each. + The fields are separated by spaces or tabs. The first five + are integer patterns to specify: + + o+ minute (0-59) + o+ hour (0-23) + o+ day of the month (1-31) + o+ month of the year (1-12) + o+ day of the week (1-7 with 1 = Monday) + + Each of these patterns may contain: + + o+ a number in the range above + o+ two numbers separated by a minus meaning a range inclusive + o+ a list of numbers separated by commas meaning any of the + numbers + o+ an asterisk meaning all legal values + + The sixth field is a user name: the command will be run with + that user's uid and permissions. The seventh field consists + of all the text on a line following the sixth field, includ- + ing spaces and tabs; this text is treated as a command which + is executed by the Shell at the specified times. A percent + character (``%'') in this field is translated to a new-line + character. + + The crontab file is checked by cron every minute, on the + minute. + +FILES + /etc/crontab diff --git a/usr.sbin/cron/cron.c b/usr.sbin/cron/cron.c new file mode 100644 index 0000000..6cb1deb --- /dev/null +++ b/usr.sbin/cron/cron.c @@ -0,0 +1,324 @@ +/* Converted to use syslog() by Phillip Vandry + #define NO_SYSLOG to get the old version */ + +#pragma stacksize 768 +#pragma optimize -1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pathnames.h" + +#define DEBUG(x) +/* #define DEBUG(x) x */ + +#define MAX_INTLIST 10 + +#define IT_ITEM 0 +#define IT_RANGE 1 +#define IT_LIST 2 +#define IT_ALL 3 + +#ifdef __ORCAC__ +#define NL 13 +#else +#define NL 10 +#endif + +typedef struct intlist { + int itype; + int count; + int intarr[MAX_INTLIST]; +} intlist; + +typedef struct ctentry { + struct ctentry *next; + intlist minute; + intlist hour; + intlist day; + intlist month; + intlist weekday; + char *user; + char *cmd; +} ctentry; + +struct ctentry *crontab = NULL; + +#ifdef NO_SYSLOG +FILE *cl; + +void cronlog(char *s) +{ +time_t t; +char *s1; + + time(&t); + s1 = ctime(&t); + s1[strlen(s1)-1] = 0; + fprintf(cl,"%s: %s\n",s1,s); +} +#endif + +void disposecrontab(void) +{ +struct ctentry *x = crontab,*x2; + + while (x) { + free(x->user); + free(x->cmd); + x2 = x->next; + free(x); + x = x2; + } + crontab = NULL; +} + +char rcbuf[256]; + +int scanws(int i) +{ + while (!(isspace(rcbuf[i]))) i++; + while (isspace(rcbuf[i])) i++; + return i; +} + +int scan2ws(int i) +{ + while ( !( isspace(rcbuf[i++]) ) ); + return i; +} + +int scandig(int i) +{ + while ( isdigit(rcbuf[i])) i++; + return i; +} + +int parseItem(int ind, struct intlist *i) +{ +int nind; +int count; + + if (rcbuf[ind] == '*') + i->itype = IT_ALL; + else { + i->itype = IT_ITEM; + sscanf(rcbuf+ind,"%d",&i->intarr[0]); + nind = scandig(ind); + if (rcbuf[nind] == ',') { + ind = nind; + count = 1; + while (rcbuf[ind] == ',') { + sscanf(rcbuf+ind+1,"%d",&i->intarr[count]); + ind = scandig(ind+1); + count++; + } + i->itype = IT_LIST; + i->count = count; + } + else if (rcbuf[nind] == '-') { + sscanf(rcbuf+nind+1,"%d",&i->intarr[1]); + ind = nind; + i->itype = IT_RANGE; + } + } + return scanws(ind); +} + +void readcrontab(void) +{ +FILE *ct; +ctentry *n; +int ind,nind; + + if (crontab) disposecrontab(); +retry: + ct = fopen(PATH_crontab,"r"); + if (ct == NULL) { +#ifndef NO_SYSLOG + syslog(LOG_ERR, "couldn't open crontab"); +#else + perror("couldn't open crontab"); + cronlog("couldn't open crontab"); +#endif + sleep(30); + goto retry; + } + while (!feof(ct)) { + if (fgets(rcbuf,255,ct) == NULL) break; + DEBUG(fprintf(stderr,"gotline %s",rcbuf)); + if (rcbuf[0] == '#') continue; + if (strlen(rcbuf) < 2) continue; + rcbuf[strlen(rcbuf)-1] = 0; + n = malloc(sizeof(ctentry)); + if (crontab) n->next = crontab; + else n->next = NULL; + crontab = n; + + ind = parseItem(0,&n->minute); + ind = parseItem(ind,&n->hour); + ind = parseItem(ind,&n->day); + ind = parseItem(ind,&n->month); + ind = parseItem(ind,&n->weekday); + nind = scan2ws(ind); + n->user = malloc(nind-ind+1); + memcpy(n->user,rcbuf+ind,nind-ind); + n->user[nind-ind] = 0; + ind = scanws(ind); + n->cmd = malloc(strlen(rcbuf)-ind+1); + strcpy(n->cmd,rcbuf+ind); + for (ind = 0; ind < strlen(n->cmd); ind++) + if (n->cmd[ind] == '%') n->cmd[ind] = NL; + rcbuf[0] = rcbuf[1] = 0; + } + fclose(ct); +} + +int matchItem(struct intlist *i,int t) +{ +int p; + + if (i->itype == IT_ALL) return 1; + else if (i->itype == IT_ITEM) { + if (t == i->intarr[0]) return 1; + else return 0; + } + else if (i->itype == IT_RANGE) { + if ((t >= i->intarr[0]) && (t <= i->intarr[1])) + return 1; + else return 0; + } + else if (i->itype == IT_LIST) { + for (p = 0; p < i->count; p++) + if (i->intarr[p] == t) return 1; + return 0; + } +} + +int matchTime(ctentry *x,struct tm *t) +{ + if (matchItem(&x->minute,t->tm_min) && + matchItem(&x->hour,t->tm_hour) && + matchItem(&x->day,t->tm_mday) && + matchItem(&x->month,t->tm_mon) /* && + matchItem(&x->weekday,t->tm_wday) */ ) + return 1; + return 0; +} + +void printItem(struct intlist *i) +{ +int p; + if (i->itype == IT_ALL) fprintf(stderr,"* "); + else if (i->itype == IT_ITEM) + fprintf(stderr,"%d ",i->intarr[0]); + else if (i->itype == IT_RANGE) + fprintf(stderr,"%d-%d",i->intarr[0],i->intarr[1]); + else if (i->itype == IT_LIST) { + fprintf(stderr,"%d",i->intarr[0]); + for (p = 1; p < i->count; p++) + fprintf(stderr,",%d",i->intarr[p]); + } +} + +void docrontab(void) +{ +struct tm *t; +time_t t1; +ctentry *x = crontab; +char *cmdpath; +word ind = 0; + + t1 = time(NULL); + t = localtime(&t1); + if (x == NULL) { /* syslog(LOG_NOTICE, "crontab empty");*/ return; } + while (x) { + DEBUG(printItem(&x->minute)); + DEBUG(printItem(&x->hour)); + DEBUG(printItem(&x->day)); + DEBUG(printItem(&x->month)); + DEBUG(printItem(&x->weekday)); + DEBUG(fprintf(stderr,":%s \n",x->cmd)); + if (matchTime(x,t)) { + DEBUG(fprintf(stderr,"matched!\n")); + ind = strpos(x->cmd,' '); + if (ind == -1) ind = strlen(x->cmd); + cmdpath = malloc(ind+1); + memcpy(cmdpath,x->cmd,ind); + cmdpath[ind] = 0; + exec(cmdpath,x->cmd); + } + x = x->next; + } +} + +int main(int argc, char *argv[]) +{ +time_t ct_mod,start_time; +unsigned int i; +struct tm *exptime; +static struct stat sb; +int sl; + +/* Previously this was a for. ORCA/C didn't compile that right, though. + This generates more efficient code anyway */ + i = 3; + while (++i < 20) close(i); +#ifndef NO_SYSLOG + openlog(NULL, 0, LOG_CRON); +#else + cl = fopen(PATH_cronlog,"a"); + if (!cl) { + perror("cron: couldn't open cronlog file"); + exit(1); + } +#endif + + /* turn off buffering so cronlog is up-to-date in the event of a + * system crash + */ +#ifdef NO_SYSLOG + setvbuf(cl,NULL,_IONBF,0l); + cronlog("cron started up"); +#else + syslog(LOG_INFO, "cron started up"); +#endif + + /* + * start cron sessions on or near an exact minute + * (giving 2 seconds leeway for 'bounce') + */ + start_time = time(NULL); + exptime = localtime(&start_time); + sleep(62 - exptime->tm_sec); + +#pragma optimize 0 /* ORCA/C has problems... */ + ct_mod = 0l; + while (1) { + DEBUG(fprintf(stderr,"loop\n")); + + stat(PATH_crontab,&sb); + if (sb.st_mtime != ct_mod) { + ct_mod = sb.st_mtime; + readcrontab(); + } +#pragma optimize 1 + docrontab(); + + /* + * account for the time we spent loading/parsing/executing + */ + start_time = time(NULL); + exptime = localtime(&start_time); + sl = 61-exptime->tm_sec; + /*while (sl < 0) sl+=60;*/ + DEBUG(fprintf(stderr,"sleep: %d\n",sl)); + sleep(sl); + } +} diff --git a/usr.sbin/cron/cronlog b/usr.sbin/cron/cronlog new file mode 100644 index 0000000..d98ea92 --- /dev/null +++ b/usr.sbin/cron/cronlog @@ -0,0 +1,3 @@ +Sat Jan 30 06:30:26 1993: cron started up +Sat Jan 30 06:30:33 1993: cron started up +Sun Jan 31 07:43:51 1993: cron started up diff --git a/usr.sbin/cron/crontab b/usr.sbin/cron/crontab new file mode 100644 index 0000000..4f7d5b7 Binary files /dev/null and b/usr.sbin/cron/crontab differ diff --git a/usr.sbin/cron/pathnames.h b/usr.sbin/cron/pathnames.h new file mode 100644 index 0000000..839557b --- /dev/null +++ b/usr.sbin/cron/pathnames.h @@ -0,0 +1,2 @@ +#define PATH_crontab "/etc/crontab" +#define PATH_cronlog "/etc/cronlog" diff --git a/usr.sbin/getty/Makefile b/usr.sbin/getty/Makefile new file mode 100644 index 0000000..1195fb1 --- /dev/null +++ b/usr.sbin/getty/Makefile @@ -0,0 +1,17 @@ +main.a: main.c pathnames.h + compile -i main.c keep=main + +init.a: init.c pathnames.h + compile -i init.c keep=init + +subr.a: subr.c + compile -i subr.c keep=subr + +gettytab.a: gettytab.c pathnames.h + compile -i +w gettytab.c keep=gettytab + +ttydflts.a: ttydefaults.c + compile -i ttydefaults.c keep=ttydflts + +getty: main.c init.c subr.c gettytab.c ttydefaults.c + compile linkfile diff --git a/usr.sbin/getty/Release.Notes b/usr.sbin/getty/Release.Notes new file mode 100644 index 0000000..813b5b9 --- /dev/null +++ b/usr.sbin/getty/Release.Notes @@ -0,0 +1,145 @@ +GNO Manual Addendum +------------------- + +This file contains information on parts of GNO that changed after +the documentation was printed. + +Known Bugs +---------- +The default gshrc file created by the installer generates a $HOME +directory that uses colon delimiters (e.g., :hd1:gno:user:root). A bug +in handling the ~ character causes attempts to, for example, "ls ~/foo" +to fail, because that gets interpreted as "ls :hd1:gno:user:root/foo", +where the system interprets "root/foo" as a single filename. You should +either change the gshrc file to use '/' delimiters, or use the ':' +delimiter when also using ~ (i.e., "ls ~:foo") + +Getty (2.0.3) +------------- +The 'getty' program provided with GNO 2.0.3 and later has a new feature and +a fixed bug. + +o Getty used to overrun its stack space in ways that were hard to + detect; this has been fixed +o There is a new type of entry in the gettytab file: + + P|8bit.9600|9600-baud-8bit|8bit:\ + :sp#9600:p8:tt=vt100:hu#8: + + The 'hu#' entry represents the RS232 signal line that is to be + used as carrier detect, and thus will cause a SIGHUP signal to + be sent to the processes running on that port. In this example, + '8' indicates a '1' in bit 3 of the following byte: + + [7] break/abort + [6] tx underrun + * [5] DSR (input handshake line) + [4] reserved + * [3] DCD (general purpose input line) + [2] tx buff empty + [1] reserved + [0] rx char available + + The only lines that have any meaning are marked with '*'s. The + default line is #5 (value 32) due to the strange wiring of some + modem cables. Setting this value to zero (0) turns off hangup + checking completely. + +How to Control Serial Ports with stty +------------------------------------- + +'stty' is short for 'set tty parameters', and can be used to control +various aspects of the serial ports and other terminal devices. + +stty modifies the parameters of the terminal that stty's standard input +references; e.g., to modify .ttya parameters, do something like this: + +stty ... < .ttya + +To set the baud rate, simply enter the baud rate you want on the command line. +e.g., to set the printer port's baud rate to 19200 baud, do + +stty 19200 <.ttyb + +The various other parameters that stty supports are described in the tty(4) +manual page. + +How to use the Multi-User package +--------------------------------- +If you choose to install the multi-user package, the nature of the GNO +system changes quite a bit. First off, instead of GNO simply being a shell +on your IIGS's screen, the console becomes a terminal through which you +can log into the system. + +When you start GNO after installing the MU package, you'll see some intro +text (terminal name, and name of the computer), and then a 'login' prompt. +At this prompt, users type in their unique user names (and normally a +password) to gain entry to your computer. GNO comes with one user already +configured : 'root'. To get into GNO the first time, type 'root' at the +login prompt. No password is set by default, so you won't be asked for one. +If you want to protect entry to your computer with a password, use the 'passwd' +command to change your password. + +% passwd + +You'll be prompted for your old password, which is nothing - so hit return. +Then you type in the new password - twice, to make sure you entered it +correctly. This is done because, sensibly, when entering a password the +keys you type are not echoed on the screen. + +Don't forget your password! If you do, you'll have to manually edit the +/etc/passwd file, and delete the second field; the one right after the username +and a colon (:), and that looks like gibberish because it's encrypted. Delete +everything between the two colons to remove the password. + +There are two ways to exit GNO with the MU package installed; simply typing +'exit' at the shell will only return to the login prompt. + +'init 5' at the shell will cause GNO to shut down and return to the program +launcher you used to run GNO (usually the Finder). + +'init 0' will shut down GNO and will reboot your computer. + +There is a file that contains a log of activity on the system, including +bad attempts to log in. This file is /var/adm/syslog. Typing +'more /var/adm/syslog' from the shell will display the contents of this file. +Other applications may also use the syslog file to record notable events. + +How to use the line printer daemon +(or, lpr is your friend) +---------------------------------- +The print spooling system included with GNO is very versatile because it +takes advantage of GNO's multitasking capabilities. Anyone can write a program +that communicates with lpd (line printer daemon) to spool a print job. At +this time the communication specification is not yet available; contact Procyon +for more information. + +You must start lpd differently depending on whether you're using the MU package +or using GNO in single-user mode. For single-user, simply type + +/usr/sbin/lpd & + +To start the spooler process. + +With MU, simply uncomment (remove the '#') the line in the /etc/inittab file +corresponding to lpd. Then, lpd will be started automatically whenever you +run GNO. Note that either way you start lpd, it is currently limited to +using the printer baud rate specified in the IIGS control panel, and to +using serial printers. lpd does not work with laser printers hooked up via +an AppleTalk network. It also requires you to use the printer port. + +There are currently two programs that use lpd; lpr, and FilePort. lpr is +the standard UNIX 'print a text file' program. Typing + +lpr file1 file2 ... + +will print the text files you list, adding headers and page numbers. + +FilePort is a GS/OS printer driver that works with desktop applications. +To turn it on, use the Control Panel NDA, select 'DC Printer', and choose +your printer type and 'FilePort' (for 'Port'). + +From then on, whenever you print from a desktop program in GNO, the output +will be spooled. If you wish to print from outside GNO, you will have to +choose the regular port driver again in the Control Panel NDA (usually +'Printer'). diff --git a/usr.sbin/getty/getty.8 b/usr.sbin/getty/getty.8 new file mode 100644 index 0000000..3a4fcd9 --- /dev/null +++ b/usr.sbin/getty/getty.8 @@ -0,0 +1,127 @@ +.\" Copyright (c) 1980, 1991 Regents of the University of California. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)getty.8 6.6 (Berkeley) 4/25/91 +.\" +.Dd April 25, 1991 +.Dt GETTY 8 +.Os BSD 4 +.Sh NAME +.Nm getty +.Nd set terminal mode +.Sh SYNOPSIS +.Nm getty +.Oo +.Ar type +.Op Ar tty +.Oc +.Sh DESCRIPTION +The +.Nm getty +program +is called by +.Xr init 8 +to open and initialize the tty line, read a login name, and invoke +.Xr login 1 . +.Pp +The argument +.Ar tty +is the special device file in +.Pa /dev +to open for the terminal (for example, ``ttyh0''). +If there is no argument or the argument is +.Ql Fl , +the tty line is assumed to be open as file descriptor 0. +.Pp +The +.Ar type +argument can be used to make +.Nm getty +treat the terminal line specially. +This argument is used as an index into the +.Nm gettytab 5 +database, to determine the characteristics of the line. +If there is no argument, or there is no such table, the +.Em default +table is used. +If there is no +.Pa /etc/gettytab +a set of system defaults is used. +If indicated by the table located, +.Nm getty +will clear the terminal screen, +print a banner heading, +and prompt for a login name. +Usually either the banner or the login prompt will include +the system hostname. +.Pp +Most of the default actions of +.Nm getty +can be circumvented, or modified, by a suitable +.Nm gettytab +table. +.Pp +The +.Nm getty +program +can be set to timeout after some interval, +which will cause dial up lines to hang up +if the login name is not entered reasonably quickly. +.Sh DIAGNOSTICS +.Bl -diag +.It "ttyxx: No such device or address." +.It "ttyxx: No such file or address." +A terminal which is turned +on in the +.Xr ttys +file cannot be opened, likely because the requisite +lines are either not configured into the system, the associated device +was not attached during boot-time system configuration, +or the special file in +.Pa /dev +does not exist. +.El +.Sh FILES +.Bl -tag -width /etc/gettytab -compact +.It Pa /etc/gettytab +.El +.Sh SEE ALSO +.Xr gettytab 5 , +.Xr init 8 , +.Xr login 1 , +.Xr ioctl 2 , +.Xr tty 4 , +.Xr ttys 5 +.Sh HISTORY +A +.Nm getty +program appeared in +.At v6 . diff --git a/usr.sbin/getty/gettytab.5 b/usr.sbin/getty/gettytab.5 new file mode 100644 index 0000000..4433c44 --- /dev/null +++ b/usr.sbin/getty/gettytab.5 @@ -0,0 +1,323 @@ +.\" Copyright (c) 1983, 1991 The Regents of the University of California. +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" 3. All advertising materials mentioning features or use of this software +.\" must display the following acknowledgement: +.\" This product includes software developed by the University of +.\" California, Berkeley and its contributors. +.\" 4. Neither the name of the University nor the names of its contributors +.\" may be used to endorse or promote products derived from this software +.\" without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" @(#)gettytab.5 6.7 (Berkeley) 5/10/91 +.\" +.Dd May 10, 1991 +.Dt GETTYTAB 5 +.Os BSD 4.2 +.Sh NAME +.Nm gettytab +.Nd terminal configuration data base +.Sh SYNOPSIS +.Nm gettytab +.Sh DESCRIPTION +The +.Nm gettytab +file +is a simplified version of the +.Xr termcap 5 +data base +used to describe terminal lines. +The initial terminal login process +.Xr getty 8 +accesses the +.Nm gettytab +file each time it starts, allowing simpler +reconfiguration of terminal characteristics. +Each entry in the data base +is used to describe one class of terminals. +.Pp +There is a default terminal class, +.Em default , +that is used to set global defaults for all other classes. +(That is, the +.Em default +entry is read, then the entry for the class required +is used to override particular settings.) +.Sh CAPABILITIES +Refer to +.Xr termcap 5 +for a description of the file layout. +The +.Em default +column below lists defaults obtained if there is +no entry in the table obtained, nor one in the special +.Em default +table. +.Bl -column Namexx /usr/bin/login Default +.It Sy Name Type Default Description +.It "ap bool false terminal uses any parity" +.It "bd num 0 backspace delay" +.It "bk str 0377 alternate end of line character (input break)" +.It "cb bool false use crt backspace mode" +.It "cd num 0 carriage-return delay" +.It "ce bool false use crt erase algorithm" +.It "ck bool false use crt kill algorithm" +.It "cl str" Ta Dv NULL Ta +.No "screen clear sequence" +.It "co bool false console - add" +.Ql \en +after login prompt +.It "ds str" Ta So Li ^Y Sc Ta +.No "delayed suspend character" +.It "dx bool false set" +.Dv DECCTLQ +.It "ec bool false leave echo" +.Tn OFF +.It "ep bool false terminal uses even parity" +.It "er str" Ta So Li ^? Sc Ta +.No "erase character" +.It "et str" Ta So Li ^D Sc Ta +.No "end of text" +.Pq Dv EOF +character +.It "ev str" Ta Dv NULL Ta +.No "initial enviroment" +.It "f0 num unused tty mode flags to write messages" +.It "f1 num unused tty mode flags to read login name" +.It "f2 num unused tty mode flags to leave terminal as" +.It "fd num 0 form-feed (vertical motion) delay" +.It "fl str" Ta So Li ^O Sc Ta +.No "output flush character" +.It "hc bool false do" +.Tn NOT +hangup line on last close +.It "he str" Ta Dv NULL Ta +.No "hostname editing string" +.It "hn str hostname hostname" +.It "ht bool false terminal has real tabs" +.It "ig bool false ignore garbage characters in login name" +.It "im str" Ta Dv NULL Ta +.No "initial (banner) message" +.It "in str" Ta So Li ^C Sc Ta +.No "interrupt character" +.It "is num unused input speed" +.It "kl str" Ta So Li ^U Sc Ta +.No "kill character" +.It "lc bool false terminal has lower case" +.It "lm str login: login prompt" +.It "ln str" Ta So Li ^V Sc Ta +.No "``literal next'' character" +.It "lo str" Ta Pa /usr/bin/login Ta +.No "program to exec when name obtained" +.It "nd num 0 newline (line-feed) delay" +.It "nl bool false terminal has (or might have) a newline character" +.It "nx str default next table (for auto speed selection)" +.It "op bool false terminal uses odd parity" +.It "os num unused output speed" +.It "pc str" Ta So Li \e0 Sc Ta +.No "pad character" +.It "pe bool false use printer (hard copy) erase algorithm" +.It "pf num 0 delay" +between first prompt and following flush (seconds) +.It "ps bool false line connected to a" +.Tn MICOM +port selector +.It "qu str" Ta So Li \&^\e Sc Ta +.No "quit character" +.It "rp str" Ta So Li ^R Sc Ta +.No "line retype character" +.It "rw bool false do" +.Tn NOT +use raw for input, use cbreak +.It "sp num unused line speed (input and output)" +.It "su str" Ta So Li ^Z Sc Ta +.No "suspend character" +.It "tc str none table continuation" +.It "to num 0 timeout (seconds)" +.It "tt str" Ta Dv NULL Ta +.No "terminal type (for environment)" +.It "ub bool false do unbuffered output (of prompts etc)" +.It "uc bool false terminal is known upper case only" +.It "we str" Ta So Li ^W Sc Ta +.No "word erase character" +.It "xc bool false do +.Tn NOT +echo control chars as +.Ql ^X +.It "xf str" Ta So Li ^S Sc Ta Dv XOFF +(stop output) character +.It "xn str" Ta So Li ^Q Sc Ta Dv XON +(start output) character +.El +.Pp +If no line speed is specified, speed will not be altered +from that which prevails when getty is entered. +Specifying an input or output speed will override +line speed for stated direction only. +.Pp +Terminal modes to be used for the output of the message, +for input of the login name, +and to leave the terminal set as upon completion, +are derived from the boolean flags specified. +If the derivation should prove inadequate, +any (or all) of these three may be overriden +with one of the +.Em \&f0 , +.Em \&f1 , +or +.Em \&f2 +numeric specifications, which can be used to specify +(usually in octal, with a leading '0') +the exact values of the flags. +Local (new tty) flags are set in the top 16 bits +of this (32 bit) value. +.Pp +Should +.Xr getty +receive a null character +(presumed to indicate a line break) +it will restart using the table indicated by the +.Em nx +entry. If there is none, it will re-use its original table. +.Pp +Delays are specified in milliseconds, the nearest possible +delay available in the tty driver will be used. +Should greater certainty be desired, delays +with values 0, 1, 2, and 3 are interpreted as +choosing that particular delay algorithm from the driver. +.Pp +The +.Em \&cl +screen clear string may be preceded by a (decimal) number +of milliseconds of delay required (a la termcap). +This delay is simulated by repeated use of the pad character +.Em \&pc . +.Pp +The initial message, and login message, +.Em \&im +and +.Em \&lm +may include the character sequence +.Em \&%h +or +.Em \&%t +to obtain +the hostname or tty name respectively. +.Pf ( Em %% +obtains a single '%' character.) +The hostname is normally obtained from the system, +but may be set by the +.Em \&hn +table entry. +In either case it may be edited with +.Em \&he . +The +.Em \&he +string is a sequence of characters, each character that +is neither '@' nor '#' is copied into the final hostname. +A '@' in the +.Em \&he +string, causes one character from the real hostname to +be copied to the final hostname. +A '#' in the +.Em \&he +string, causes the next character of the real hostname +to be skipped. +Surplus '@' and '#' characters are ignored. +.Pp +When getty execs the login process, given +in the +.Em \&lo +string (usually +.Dq Pa /usr/bin/login ) , +it will have set +the enviroment to include the terminal type, as indicated +by the +.Em \&tt +string (if it exists). +The +.Em \&ev +string, can be used to enter additional data into +the environment. +It is a list of comma separated strings, each of which +will presumably be of the form +.Em name=value . +.Pp +If a non-zero timeout is specified, with +.Em \&to , +then getty will exit within the indicated +number of seconds, either having +received a login name and passed control +to +.Xr login , +or having received an alarm signal, and exited. +This may be useful to hangup dial in lines. +.Pp +Output from +.Xr getty +is even parity unless +.Em \&op +is specified. +The +.Em \&op +string +may be specified with +.Em \&ap +to allow any parity on input, but generate odd parity output. +Note: this only applies while getty is being run, +terminal driver limitations prevent a more complete +implementation. +.Xr Getty +does not check parity of input characters in +.Dv RAW +mode. +.Sh SEE ALSO +.Xr login 1 , +.Xr termcap 5 , +.Xr getty 8 . +.Sh BUGS +The special characters (erase, kill, etc.) are reset to system defaults +by +.Xr login 1 . +In +.Em all +cases, '#' or '^H' typed in a login name will be treated as +an erase character, and '@' will be treated as a kill character. +.Pp +The delay stuff is a real crock. +Apart form its general lack of flexibility, some +of the delay algorithms are not implemented. +The terminal driver should support sane delay settings. +.Pp +The +.Em \&he +capability is stupid. +.Pp +The +.Xr termcap +format is horrid, something more rational should +have been chosen. +.Sh HISTORY +The +.Nm gettytab +file format appeared in 4.2BSD. diff --git a/usr.sbin/getty/gettytab.c b/usr.sbin/getty/gettytab.c new file mode 100644 index 0000000..f8e18bf --- /dev/null +++ b/usr.sbin/getty/gettytab.c @@ -0,0 +1,354 @@ +/*#pragma debug 25*/ +/*#define BUG(__s) {fprintf(stderr,"%s\n",__s);}*/ +#define BUG(__s) +#pragma optimize 31 + +/* + * Copyright (c) 1983 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)gettytab.c 5.5 (Berkeley) 2/25/91"; +#endif /* not lint */ + +#include +#include +#include +#include +#include +#include +#include "pathnames.h" + +#define TABBUFSIZ 512 + +static char *tbuf; +int hopcount; /* detect infinite loops in termcap, init 0 */ +char *skip(); +char *getstr(); +char *decode(); + +/* + * Get an entry for terminal name in buffer bp, + * from the termcap file. Parse is very rudimentary; + * we just notice escaped newlines. + */ +getent(bp, name) + char *bp, *name; +{ + register char *cp; + register int c; + register int i = 0, cnt = 0; + static char ibuf[TABBUFSIZ]; + char *cp2; + int tf; + + tbuf = bp; + tf = open(_PATH_GETTYTAB, O_RDONLY); + if (tf < 0) + return (-1); + for (;;) { + cp = bp; + for (;;) { + if (i == cnt) { + cnt = read(tf, ibuf, TABBUFSIZ); + if (cnt <= 0) { + close(tf); + return (0); + } + i = 0; + } + c = ibuf[i++]; + if (c == '\n' || c == '\r') { + if (cp > bp && cp[-1] == '\\'){ + cp--; + continue; + } + break; + } + if (cp >= bp+TABBUFSIZ) { + write(STDERR_FILENO,"Gettytab entry too long\n", 24); + break; + } else + *cp++ = c; + } + *cp = 0; + + /* + * The real work for the match. + */ + if (namatch(name)) { + close(tf); + return(nchktc()); + } + } +} + +/* + * tnchktc: check the last entry, see if it's tc=xxx. If so, + * recursively find xxx and append that entry (minus the names) + * to take the place of the tc=xxx entry. This allows termcap + * entries to say "like an HP2621 but doesn't turn on the labels". + * Note that this works because of the left to right scan. + */ +#define MAXHOP 32 +nchktc() +{ + register char *p, *q; + char tcname[16]; /* name of similar terminal */ + char *tcbuf; + /*char tcbuf[TABBUFSIZ];*/ + char *holdtbuf = tbuf; + int l; + + tcbuf = malloc(TABBUFSIZ); + p = tbuf + strlen(tbuf) - 2; /* before the last colon */ + while (*--p != ':') + if (p MAXHOP) { + write(STDERR_FILENO, "Getty: infinite tc= loop\n", 25); + free(tcbuf); + return (0); + } + if (getent(tcbuf, tcname) != 1) { + free(tcbuf); + return(0); + } + for (q=tcbuf; *q != ':'; q++) + ; + l = p - holdtbuf + strlen(q); + if (l > TABBUFSIZ) { + write(STDERR_FILENO, "Gettytab entry too long\n", 24); + q[TABBUFSIZ - (p-tbuf)] = 0; + } + strcpy(p, q+1); + tbuf = holdtbuf; + free(tcbuf); + return(1); +} + +/* + * Tnamatch deals with name matching. The first field of the termcap + * entry is a sequence of names separated by |'s, so we compare + * against each such name. The normal : terminator after the last + * name (before the first field) stops us. + */ +namatch(char *np) +{ + register char *Np, *Bp; + + Bp = tbuf; + if (*Bp == '#') + return(0); + for (;;) { + for (Np = np; *Np && *Bp == *Np; Bp++, Np++) + continue; + if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0)) + return (1); + while (*Bp && *Bp != ':' && *Bp != '|') + Bp++; + if (*Bp == 0 || *Bp == ':') + return (0); + Bp++; + } +} + +/* + * Skip to the next field. Notice that this is very dumb, not + * knowing about \: escapes or any such. If necessary, :'s can be put + * into the termcap file in octal. + */ +static char * +skip(bp) + register char *bp; +{ + + while (*bp && *bp != ':') + bp++; + if (*bp == ':') + bp++; + return (bp); +} + +/* + * Return the (numeric) option id. + * Numeric options look like + * li#80 + * i.e. the option string is separated from the numeric value by + * a # character. If the option is not found we return -1. + * Note that we handle octal numbers beginning with 0. + */ +long +getnum(id) + char *id; +{ + register long i, base; + register char *bp = tbuf; + + for (;;) { + bp = skip(bp); + if (*bp == 0) + return (-1); + if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1]) + continue; + if (*bp == '@') + return(-1); + if (*bp != '#') + continue; + bp++; + base = 10; + if (*bp == '0') + base = 8; + i = 0; + while (isdigit(*bp)) + i *= base, i += *bp++ - '0'; + return (i); + } +} + +/* + * Handle a flag option. + * Flag options are given "naked", i.e. followed by a : or the end + * of the buffer. Return 1 if we find the option, or 0 if it is + * not given. + */ +getflag(id) + char *id; +{ + register char *bp = tbuf; + + for (;;) { + bp = skip(bp); + if (!*bp) + return (-1); + if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) { + if (!*bp || *bp == ':') + return (1); + else if (*bp == '!') + return (0); + else if (*bp == '@') + return(-1); + } + } +} + +/* + * Get a string valued option. + * These are given as + * cl=^Z + * Much decoding is done on the strings, and the strings are + * placed in area, which is a ref parameter which is updated. + * No checking on area overflow. + */ +char * +getstr(id, area) + char *id, **area; +{ + register char *bp = tbuf; + + for (;;) { + bp = skip(bp); + if (!*bp) + return (0); + if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1]) + continue; + if (*bp == '@') + return(0); + if (*bp != '=') + continue; + bp++; + return (decode(bp, area)); + } +} + +/* + * Tdecode does the grung work to decode the + * string capability escapes. + */ +static char * +decode(str, area) + register char *str; + char **area; +{ + register char *cp; + register int c; + register char *dp; + int i; + + cp = *area; + while ((c = *str++) && c != ':') { + switch (c) { + + case '^': + c = *str++ & 037; + break; + + case '\\': + dp = "E\033^^\\\\::n\nr\rt\tb\bf\f"; + c = *str++; +nextc: + if (*dp++ == c) { + c = *dp++; + break; + } + dp++; + if (*dp) + goto nextc; + if (isdigit(c)) { + c -= '0', i = 2; + do + c <<= 3, c |= *str++ - '0'; + while (--i && isdigit(*str)); + } + break; + } + *cp++ = c; + } + *cp++ = 0; + str = *area; + *area = cp; + return (str); +} diff --git a/usr.sbin/getty/gettytab.h b/usr.sbin/getty/gettytab.h new file mode 100644 index 0000000..2543c56 --- /dev/null +++ b/usr.sbin/getty/gettytab.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 1983 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)gettytab.h 5.5 (Berkeley) 3/27/91 + */ + +/* + * Getty description definitions. + */ +struct gettystrs { + char *field; /* name to lookup in gettytab */ + char *defalt; /* value we find by looking in defaults */ + char *value; /* value that we find there */ +}; + +struct gettynums { + char *field; /* name to lookup */ + long defalt; /* number we find in defaults */ + long value; /* number we find there */ + int set; /* we actually got this one */ +}; + +struct gettyflags { + char *field; /* name to lookup */ + char invrt; /* name existing in gettytab --> false */ + char defalt; /* true/false in defaults */ + char value; /* true/false flag */ + char set; /* we found it */ +}; + +/* + * String values. + */ +#define NX gettystrs[0].value +#define CL gettystrs[1].value +#define IM gettystrs[2].value +#define LM gettystrs[3].value +#define ER gettystrs[4].value +#define KL gettystrs[5].value +#define ET gettystrs[6].value +#define PC gettystrs[7].value +#define TT gettystrs[8].value +#define EV gettystrs[9].value +#define LO gettystrs[10].value +#define HN gettystrs[11].value +#define HE gettystrs[12].value +#define IN gettystrs[13].value +#define QU gettystrs[14].value +#define XN gettystrs[15].value +#define XF gettystrs[16].value +#define BK gettystrs[17].value +#define SU gettystrs[18].value +#define DS gettystrs[19].value +#define RP gettystrs[20].value +#define FL gettystrs[21].value +#define WE gettystrs[22].value +#define LN gettystrs[23].value + +/* + * Numeric definitions. + */ +#define IS gettynums[0].value +#define OS gettynums[1].value +#define SP gettynums[2].value +#define ND gettynums[3].value +#define CD gettynums[4].value +#define TD gettynums[5].value +#define FD gettynums[6].value +#define BD gettynums[7].value +#define TO gettynums[8].value +#define F0 gettynums[9].value +#define F0set gettynums[9].set +#define F1 gettynums[10].value +#define F1set gettynums[10].set +#define F2 gettynums[11].value +#define F2set gettynums[11].set +#define PF gettynums[12].value +#define HU gettynums[13].value +#define HUset gettynums[13].set + +/* + * Boolean values. + */ +#define HT gettyflags[0].value +#define NL gettyflags[1].value +#define EP gettyflags[2].value +#define EPset gettyflags[2].set +#define OP gettyflags[3].value +#define OPset gettyflags[2].set +#define AP gettyflags[4].value +#define APset gettyflags[2].set +#define EC gettyflags[5].value +#define CO gettyflags[6].value +#define CB gettyflags[7].value +#define CK gettyflags[8].value +#define CE gettyflags[9].value +#define PE gettyflags[10].value +#define RW gettyflags[11].value +#define XC gettyflags[12].value +#define LC gettyflags[13].value +#define UC gettyflags[14].value +#define IG gettyflags[15].value +#define PS gettyflags[16].value +#define HC gettyflags[17].value +#define UB gettyflags[18].value +#define AB gettyflags[19].value +#define DX gettyflags[20].value +#define NP gettyflags[21].value + +int getent(); +long getnum(); +int getflag(); +char *getstr(); + +extern struct gettyflags gettyflags[]; +extern struct gettynums gettynums[]; +extern struct gettystrs gettystrs[]; +extern int hopcount; diff --git a/usr.sbin/getty/init.c b/usr.sbin/getty/init.c new file mode 100644 index 0000000..38f2aa8 --- /dev/null +++ b/usr.sbin/getty/init.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 1983 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)init.c 5.6 (Berkeley) 3/27/91"; +#endif /* not lint */ + +/* + * Getty table initializations. + * + * Melbourne getty. + */ +#include +#include "gettytab.h" +#include "pathnames.h" + +extern struct sgttyb tmode; +extern struct tchars tc; +extern struct ltchars ltc; +extern char hostname[]; + +struct gettystrs gettystrs[] = { + { "nx" }, /* next table */ + { "cl" }, /* screen clear characters */ + { "im" }, /* initial message */ + { "lm", "login: " }, /* login message */ + { "er", &tmode.sg_erase }, /* erase character */ + { "kl", &tmode.sg_kill }, /* kill character */ + { "et", &tc.t_eofc }, /* eof chatacter (eot) */ + { "pc", "" }, /* pad character */ + { "tt" }, /* terminal type */ + { "ev" }, /* enviroment */ + { "lo", _PATH_LOGIN }, /* login program */ + { "hn", hostname }, /* host name */ + { "he" }, /* host name edit */ + { "in", &tc.t_intrc }, /* interrupt char */ + { "qu", &tc.t_quitc }, /* quit char */ + { "xn", &tc.t_startc }, /* XON (start) char */ + { "xf", &tc.t_stopc }, /* XOFF (stop) char */ + { "bk", &tc.t_brkc }, /* brk char (alt \n) */ + { "su", <c.t_suspc }, /* suspend char */ + { "ds", <c.t_dsuspc }, /* delayed suspend */ + { "rp", <c.t_rprntc }, /* reprint char */ + { "fl", <c.t_flushc }, /* flush output */ + { "we", <c.t_werasc }, /* word erase */ + { "ln", <c.t_lnextc }, /* literal next */ + { 0 } +}; + +struct gettynums gettynums[] = { + { "is" }, /* input speed */ + { "os" }, /* output speed */ + { "sp" }, /* both speeds */ + { "nd" }, /* newline delay */ + { "cd" }, /* carriage-return delay */ + { "td" }, /* tab delay */ + { "fd" }, /* form-feed delay */ + { "bd" }, /* backspace delay */ + { "to" }, /* timeout */ + { "f0" }, /* output flags */ + { "f1" }, /* input flags */ + { "f2" }, /* user mode flags */ + { "pf" }, /* delay before flush at 1st prompt */ + { "hu" }, /* sighup control value */ + { 0 } +}; + +struct gettyflags gettyflags[] = { + { "ht", 0 }, /* has tabs */ + { "nl", 1 }, /* has newline char */ + { "ep", 0 }, /* even parity */ + { "op", 0 }, /* odd parity */ + { "ap", 0 }, /* any parity */ + { "ec", 1 }, /* no echo */ + { "co", 0 }, /* console special */ + { "cb", 0 }, /* crt backspace */ + { "ck", 0 }, /* crt kill */ + { "ce", 0 }, /* crt erase */ + { "pe", 0 }, /* printer erase */ + { "rw", 1 }, /* don't use raw */ + { "xc", 1 }, /* don't ^X ctl chars */ + { "lc", 0 }, /* terminal las lower case */ + { "uc", 0 }, /* terminal has no lower case */ + { "ig", 0 }, /* ignore garbage */ + { "ps", 0 }, /* do port selector speed select */ + { "hc", 1 }, /* don't set hangup on close */ + { "ub", 0 }, /* unbuffered output */ + { "ab", 0 }, /* auto-baud detect with '\r' */ + { "dx", 0 }, /* set decctlq */ + { "np", 0 }, /* no parity at all (8bit chars) */ + { 0 } +}; diff --git a/usr.sbin/getty/init.disasm b/usr.sbin/getty/init.disasm new file mode 100644 index 0000000..f78b96f --- /dev/null +++ b/usr.sbin/getty/init.disasm @@ -0,0 +1,192 @@ +DumpOBJ 2.0 + +Byte count : $00000382 898 +Reserved space: $00000000 0 +Length : $00000165 357 +Label length : $00 0 +Number length : $04 4 +Version : $02 2 +Bank size : $00010000 65536 +Kind : $0000 0 (code,static) +Org : $00000000 0 +Alignment : $00000000 0 +Number sex : $00 0 +Segment number: $0000 0 +Segment entry : $00000000 0 +Disp to names : $0030 48 +Disp to body : $0044 68 +Load name : +Segment name : login_tty + +000044 000000 | LONGA ON +000044 000000 | LONGI ON +000044 000000 | login_tty START +000044 000000 | TSC +000046 000001 | SEC +000047 000002 | SBC #$0008 +00004A 000005 | TCS +00004B 000006 | PHD +00004C 000007 | TCD +00004D 000008 | TSC +00004E 000009 | STA $07 +000050 00000B | LDA $07 +000052 00000D | PHA +000053 00000E | PEA ((login_tty+$0000010A)|$FFFFFFF0) +000062 000011 | PEA (login_tty+$0000010A) +00006C 000014 | JSL printf +000079 000018 | BRK $00 +00007C 00001A | LDA $0C +00007E 00001C | PHA +00007F 00001D | JSL tcnewpgrp +00008E 000021 | LDX #$0000 +000092 000024 | CMP #$FFFF +000095 000027 | BNE (login_tty+$0000002A) +0000A2 000029 | INX +0000A4 00002A | TXA +0000A6 00002B | BNE (login_tty+$00000030) +0000B3 00002D | BRL (login_tty+$0000003A) +0000C1 000030 | PEA (((login_tty+$0000010A)+$00000010)|$FFFFFFF0) +0000D7 000033 | PEA ((login_tty+$0000010A)+$00000010) +0000E7 000036 | JSL printf +0000F4 00003A | LDA $0C +0000F7 00003C | PHA +0000F8 00003D | JSL settpgrp +000106 000041 | LDA #$FFFF +00010A 000044 | LDX #$0000 +00010D 000047 | TAY +00010E 000048 | BPL (login_tty+$0000004B) +00011B 00004A | DEX +00011D 00004B | LDY #$0001 +000121 00004E | CMP $01,S +000123 000050 | BEQ (login_tty+$00000053) +000130 000052 | DEY +000132 000053 | TXA +000134 000054 | CMP $03,S +000136 000056 | BEQ (login_tty+$0000005B) +000143 000058 | LDY #$0000 +000147 00005B | PLA +000149 00005C | PLA +00014A 00005D | TYA +00014B 00005E | BNE (login_tty+$00000063) +000158 000060 | BRL (login_tty+$0000006D) +000166 000063 | PEA (((login_tty+$0000010A)+$00000022)|$FFFFFFF0) +00017C 000066 | PEA ((login_tty+$0000010A)+$00000022) +00018C 000069 | JSL printf +000199 00006D | PEA $0000 +00019D 000070 | PEA $0000 +0001A0 000073 | PEA $2000 +0001A3 000076 | PEA $7461 +0001A6 000079 | LDA $0C +0001A8 00007B | PHA +0001A9 00007C | JSL ioctl +0001B4 000080 | LDX #$0000 +0001B8 000083 | CMP #$FFFF +0001BB 000086 | BNE (login_tty+$00000089) +0001C8 000088 | INX +0001CA 000089 | TXA +0001CC 00008A | BNE (login_tty+$0000008F) +0001D9 00008C | BRL (login_tty+$000000A1) +0001E7 00008F | PEA (((login_tty+$0000010A)+$00000033)|$FFFFFFF0) +0001FD 000092 | PEA ((login_tty+$0000010A)+$00000033) +00020D 000095 | JSL printf +00021A 000099 | LDA #$FFFF +00021E 00009C | STA $01 +000220 00009E | BRL (login_tty+$000000F7) +00022D 0000A1 | LDA #$0001 +000231 0000A4 | PHA +000232 0000A5 | LDA $0C +000234 0000A7 | PHA +000235 0000A8 | JSL dup2 +00023F 0000AC | LDA #$0002 +000243 0000AF | PHA +000244 0000B0 | LDA $0C +000246 0000B2 | PHA +000247 0000B3 | JSL dup2 +000251 0000B7 | LDA #$0003 +000255 0000BA | PHA +000256 0000BB | LDA $0C +000258 0000BD | PHA +000259 0000BE | JSL dup2 +000263 0000C2 | LDA $0C +000266 0000C4 | LDX #$0001 +000269 0000C7 | SEC +00026A 0000C8 | SBC #$0003 +00026D 0000CB | BEQ (login_tty+$000000D4) +00027A 0000CD | BVS (login_tty+$000000D2) +000288 0000CF | EOR #$8000 +00028C 0000D2 | BMI (login_tty+$000000D5) +00029A 0000D4 | DEX +00029C 0000D5 | TXA +00029E 0000D6 | BNE (login_tty+$000000DB) +0002AB 0000D8 | BRL (login_tty+$000000E2) +0002B9 0000DB | LDA $0C +0002BC 0000DD | PHA +0002BD 0000DE | JSL close +0002C8 0000E2 | TSC +0002CA 0000E3 | STA $07 +0002CC 0000E5 | LDA $07 +0002CE 0000E7 | PHA +0002CF 0000E8 | PEA (((login_tty+$0000010A)+$0000004B)|$FFFFFFF0) +0002E4 0000EB | PEA ((login_tty+$0000010A)+$0000004B) +0002F4 0000EE | JSL printf +000301 0000F2 | STZ $01 +000304 0000F4 | BRL (login_tty+$000000F7) +000311 0000F7 | LDA $0A +000314 0000F9 | STA $0C +000316 0000FB | LDA $09 +000318 0000FD | STA $0B +00031A 0000FF | LDY $01 +00031C 000101 | PLD +00031D 000102 | TSC +00031E 000103 | CLC +00031F 000104 | ADC #$000A +000322 000107 | TCS +000323 000108 | TYA +000324 000109 | RTL +000325 00010A | ADC ($74,S),Y +000328 00010C | ADC ($63,X) +00032A 00010E | RTL +00032B 00010F | JSR $7369 +00032E 000112 | DEC A +00032F 000113 | JSR $3025 +000332 000116 | BIT $58,X +000334 000118 | ASL A +000335 000119 | BRK $74 +000337 00011B | ADC $6E,S +000339 00011D | ADC $77 +00033B 00011F | BVS *+$69 +00033D 000121 | ADC ($70) +00033F 000123 | JSR $6166 +000342 000126 | ADC #$656C +000345 000129 | STZ $0A +000347 00012B | BRK $73 +000349 00012D | ADC $74 +00034B 00012F | STZ $70,X +00034D 000131 | ADC [$72] +00034F 000133 | BVS *+$22 +000351 000135 | ROR $61 +000353 000137 | ADC #$656C +000356 00013A | STZ $0A +000358 00013C | BRK $69 +00035A 00013E | ADC >$6C7463 +00035E 000142 | AND >$4F4954 +000362 000146 | EOR $53,S +000364 000148 | EOR $54,S +000366 00014A | MVN $59,$20 +000369 00014D | ROR $61 +00036B 00014F | ADC #$656C +00036E 000152 | STZ $0A +000370 000154 | BRK $73 +000372 000156 | STZ $61,X +000374 000158 | ADC $6B,S +000376 00015A | JSR $7369 +000379 00015D | DEC A +00037A 00015E | JSR $3025 +00037D 000161 | BIT $58,X +00037F 000163 | ASL A +000380 000164 | BRK ??? +000382 000166 | +000383 000166 | END + + + diff --git a/usr.sbin/getty/linkfile b/usr.sbin/getty/linkfile new file mode 100755 index 0000000..eadfb8c --- /dev/null +++ b/usr.sbin/getty/linkfile @@ -0,0 +1,8 @@ +main +init +subr +gettytab +ttydflts +../strftime/strftime +2/libgno +keep=getty diff --git a/usr.sbin/getty/main.c b/usr.sbin/getty/main.c new file mode 100644 index 0000000..07769b9 --- /dev/null +++ b/usr.sbin/getty/main.c @@ -0,0 +1,554 @@ +/*#define BUG(__s) {fprintf(stderr,"%s\n",__s);}*/ +#pragma optimize 31 +#pragma stacksize 1024 +#define BUG(__s) +#define rindex strrchr + +/*- + * Copyright (c) 1980 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +char copyright[] = +"@(#) Copyright (c) 1980 The Regents of the University of California.\n\ + All rights reserved.\n"; +#endif /* not lint */ + +#ifndef lint +static char sccsid[] = "@(#)main.c 5.16 (Berkeley) 3/27/91"; +#endif /* not lint */ + +#define USE_OLD_TTY + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gettytab.h" +#include "pathnames.h" + +#ifndef HOSTNAME +#define MAXHOSTNAMELEN 10 +gethostname(char *name, int namelen) +{ + strncpy(name,"apple",namelen); + return 0; +} +#endif + +struct sgttyb tmode = { + 0, 0, CERASE, CKILL, 0 +}; +struct tchars tc = { + CINTR, CQUIT, CSTART, + CSTOP, CEOF, CBRK, +}; +struct ltchars ltc = { + CSUSP, CDSUSP, CRPRNT, + CFLUSH, CWERASE, CLNEXT +}; + +int crmod, digit, lower, upper; + +char hostname[MAXHOSTNAMELEN]; +char name[16]; +char dev[] = _PATH_DEV; +char ttyn[32]; +char *portselector(); + +#ifdef __ORCAC__ +char *ttyname(int fino); +#else +char *ttyname(); +#endif + +#define OBUFSIZ 128 +#define TABBUFSIZ 512 + +char defent[TABBUFSIZ]; +char defstrs[TABBUFSIZ]; +char tabent[TABBUFSIZ]; +char tabstrs[TABBUFSIZ]; + +#ifndef __ORCAC__ +char *env[128]; +#endif + +char partab[] = { + 0001,0201,0201,0001,0201,0001,0001,0201, + 0202,0004,0003,0205,0005,0206,0201,0001, + 0201,0001,0001,0201,0001,0201,0201,0001, + 0001,0201,0201,0001,0201,0001,0001,0201, + 0200,0000,0000,0200,0000,0200,0200,0000, + 0000,0200,0200,0000,0200,0000,0000,0200, + 0000,0200,0200,0000,0200,0000,0000,0200, + 0200,0000,0000,0200,0000,0200,0200,0000, + 0200,0000,0000,0200,0000,0200,0200,0000, + 0000,0200,0200,0000,0200,0000,0000,0200, + 0000,0200,0200,0000,0200,0000,0000,0200, + 0200,0000,0000,0200,0000,0200,0200,0000, + 0000,0200,0200,0000,0200,0000,0000,0200, + 0200,0000,0000,0200,0000,0200,0200,0000, + 0200,0000,0000,0200,0000,0200,0200,0000, + 0000,0200,0200,0000,0200,0000,0000,0201 +}; + +#define ERASE tmode.sg_erase +#define KILL tmode.sg_kill +#define EOT tc.t_eofc + +jmp_buf timeout; + +static void +dingdong(int sig, int code) +{ + + alarm(0); + signal(SIGALRM, SIG_DFL); + longjmp(timeout, 1); +} + +jmp_buf intrupt; + +static void +interrupt(int sig, int code) +{ + + signal(SIGINT, interrupt); + longjmp(intrupt, 1); +} + +main(argc, argv) + int argc; + char **argv; +{ +#ifndef __ORCAC__ + extern char **environ; +#endif + char *tname; + long allflags; + int repcnt = 0; + int tmp; + + signal(SIGINT, SIG_IGN); +/* + signal(SIGQUIT, SIG_DFL); +*/ + openlog("getty", LOG_ODELAY|LOG_CONS, LOG_AUTH); + gethostname(hostname, sizeof(hostname)); + if (hostname[0] == '\0') + strcpy(hostname, "Amnesiac"); + /* + * The following is a work around for vhangup interactions + * which cause great problems getting window systems started. + * If the tty line is "-", we do the old style getty presuming + * that the file descriptors are already set up for us. + * J. Gettys - MIT Project Athena. + */ + if (argc <= 2 || strcmp(argv[2], "-") == 0) { + char *temp = ttyname(STDIN_FILENO); + if (temp) strcpy(ttyn, temp); else *ttyn = 0; + } else { + int i; + +#ifdef __ORCAC__ + strcpy(ttyn,argv[2]); +#else + strcpy(ttyn, dev); + strncat(ttyn, argv[2], sizeof(ttyn)-sizeof(dev)); +#endif + if (strcmp(argv[0], "+") != 0) { +/* chown(ttyn, 0, 0); */ +/* chmod(ttyn, 0600); */ +/* revoke(ttyn); */ + /* + * Delay the open so DTR stays down long enough to be detected. + */ +/* sleep(2); */ + while ((i = open(ttyn, O_RDWR)) == -1) { + if (repcnt % 10 == 0) { + syslog(LOG_ERR, "%s: %m", ttyn); + closelog(); + } + repcnt++; + sleep(60); + } + login_tty(i); /* ??? */ + } + } + gettable("default", defent, defstrs); + gendefaults(); + tname = "default"; + if (argc > 1) + tname = argv[1]; + for (;;) { + int ldisp = OTTYDISC; + int off = 0; + + gettable(tname, tabent, tabstrs); + if (OPset || EPset || APset) + APset++, OPset++, EPset++; + setdefaults(); + ioctl(STDIN_FILENO, TIOCFLUSH, 0); /* clear out the crap */ + ioctl(STDIN_FILENO, FIONBIO, &off); /* turn off non-blocking mode */ + ioctl(STDIN_FILENO, FIOASYNC, &off); /* ditto for async mode */ + if (IS) + tmode.sg_ispeed = speed(IS); + else if (SP) + tmode.sg_ispeed = speed(SP); + if (OS) + tmode.sg_ospeed = speed(OS); + else if (SP) + tmode.sg_ospeed = speed(SP); + tmode.sg_flags = setflags(0); + ioctl(STDIN_FILENO, TIOCSETP, &tmode); + setchars(); + ioctl(STDIN_FILENO, TIOCSETC, &tc); + if (HUset) + ioctl(STDIN_FILENO, TIOCSHUP, &HU); + if (HC) + ioctl(STDIN_FILENO, TIOCHPCL, 0); + if (AB) { + extern char *autobaud(); + + tname = autobaud(); + continue; + } + if (PS) { + tname = portselector(); + continue; + } + if (CL && *CL) + putpad(CL); + edithost(HE); + if (IM && *IM) + putf(IM); + if (setjmp(timeout)) { + tmode.sg_ispeed = tmode.sg_ospeed = 0; + ioctl(STDIN_FILENO, TIOCSETP, &tmode); + exit(1); + } + if (TO) { + signal(SIGALRM, dingdong); + alarm(TO); + } + tmp = getname(); + /*printf("\r\n\t\t\ttmp: %d\n\r",tmp);*/ + fflush(stdout); + if (tmp) { + /*if (getname()) {*/ +#ifndef __ORCAC__ + register int i; +#endif + + oflush(); + alarm(0); + signal(SIGALRM, SIG_DFL); + if (name[0] == '-') { + puts("user names may not start with '-'."); + continue; + } + if (!(upper || lower || digit)) + continue; + allflags = setflags(2); + tmode.sg_flags = allflags & 0xffff; + allflags >>= 16; + if (crmod || NL) + tmode.sg_flags |= CRMOD; + if (upper || UC) + tmode.sg_flags |= LCASE; + if (lower || LC) + tmode.sg_flags &= ~LCASE; + tmode.sg_erase = 0x7f; + ioctl(STDIN_FILENO, TIOCSETP, &tmode); + ioctl(STDIN_FILENO, TIOCSLTC, <c); + ioctl(STDIN_FILENO, TIOCLSET, &allflags); + signal(SIGINT, SIG_DFL); +#ifdef __ORCAC__ + BUG("making environment"); + makeenv(); + BUG("made environment"); +#else + for (i = 0; environ[i] != (char *)0; i++) + env[i] = environ[i]; + makeenv(&env[i]); +#endif + + /* + * this is what login was doing anyway. + * soon we rewrite getty completely. + */ + set_ttydefaults(STDIN_FILENO); +#ifdef __ORCAC__ + { + static char temp[256]; + sprintf(temp,"login -p %s",name); + execve(LO,temp); + } +#else + execle(LO, "login", "-p", name, (char *) 0, env); +#endif + syslog(LOG_ERR, "%s: %m", LO); + exit(1); + } + alarm(0); + signal(SIGALRM, SIG_DFL); + signal(SIGINT, SIG_IGN); + if (NX && *NX) + tname = NX; + } +} + +getname() +{ + register int c; + register char *np; + char cs; + + /* + * Interrupt may happen if we use CBREAK mode + */ + if (setjmp(intrupt)) { + signal(SIGINT, SIG_IGN); + return (0); + } + signal(SIGINT, interrupt); + tmode.sg_flags = setflags(0); + ioctl(STDIN_FILENO, TIOCSETP, &tmode); + tmode.sg_flags = setflags(1); + /*printf("flags: %04X\n",tmode.sg_flags);*/ + prompt(); + if (PF > 0) { + oflush(); + sleep(PF); + PF = 0; + } + ioctl(STDIN_FILENO, TIOCSETP, &tmode); + crmod = digit = lower = upper = 0; + np = name; + for (;;) { + oflush(); + if (read(STDIN_FILENO, &cs, 1) <= 0) + exit(0); + if ((c = cs&0177) == 0) + return (0); + if (c == EOT) + exit(1); + if (c == '\r' || c == '\n' || np >= &name[sizeof name]) { + putf("\r\n"); + break; + } + if (islower(c)) + lower = 1; + else if (isupper(c)) + upper = 1; + else if (c == ERASE || c == '#' || c == '\b' || c == 0x7f) { + if (np > name) { + np--; + if (tmode.sg_ospeed >= B1200) + puts("\b \b"); + else + putchr(cs); + } + continue; + } else if (c == KILL || c == '@') { + putchr(cs); + putchr('\r'); + if (tmode.sg_ospeed < B1200) + putchr('\n'); + /* this is the way they do it down under ... */ + else if (np > name) + puts(" \r"); + prompt(); + np = name; + continue; + } else if (isdigit(c)) + digit++; + if (IG && (c <= ' ' || c > 0176)) + continue; + *np++ = c; + putchr(cs); + } + signal(SIGINT, SIG_IGN); + *np = 0; + if (c == '\r') + crmod = 1; + if (upper && !lower && !LC || UC) + for (np = name; *np; np++) + if (isupper(*np)) + *np = tolower(*np); + return (1); +} + +static +short tmspc10[] = { + 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5, 15 +}; + +putpad(char *s) +{ + register pad = 0; + register mspc10; + + if (isdigit(*s)) { + while (isdigit(*s)) { + pad *= 10; + pad += *s++ - '0'; + } + pad *= 10; + if (*s == '.' && isdigit(s[1])) { + pad += s[1] - '0'; + s += 2; + } + } + + puts(s); + /* + * If no delay needed, or output speed is + * not comprehensible, then don't try to delay. + */ + if (pad == 0) + return; + if (tmode.sg_ospeed <= 0 || + tmode.sg_ospeed >= (sizeof tmspc10 / sizeof tmspc10[0])) + return; + + /* + * Round up by a half a character frame, and then do the delay. + * Too bad there are no user program accessible programmed delays. + * Transmitting pad characters slows many terminals down and also + * loads the system. + */ + mspc10 = tmspc10[tmode.sg_ospeed]; + pad += mspc10 / 2; + for (pad /= mspc10; pad > 0; pad--) + putchr(*PC); +} + +/* odd, another prototyping bug */ +puts(char *s) + /*register char *s;*/ +{ + while (*s) + putchr(*s++); +} + +char outbuf[OBUFSIZ]; +int obufcnt = 0; + +putchr(cc) +{ + char c; + + c = cc; + if (!NP) { + c |= partab[c&0177] & 0200; + if (OP) + c ^= 0200; + } + if (!UB) { + outbuf[obufcnt++] = c; + if (obufcnt >= OBUFSIZ) + oflush(); + } else + write(STDOUT_FILENO, &c, 1); +} + +oflush() +{ + if (obufcnt) + write(STDOUT_FILENO, outbuf, obufcnt); + obufcnt = 0; +} + +prompt() +{ + + putf(LM); + if (CO) + putchr('\n'); +} + +putf(char *cp) +{ + extern char editedhost[]; + time_t t; + char *slash; + static char db[100]; + + while (*cp) { + if (*cp != '%') { + putchr(*cp++); + continue; + } + switch (*++cp) { + + case 't': + slash = rindex(ttyn, '/'); + if (slash == NULL) + puts(ttyn); + else + puts(&slash[1]); + break; + + case 'h': + puts(editedhost); + break; + + case 'd': { + static char fmt[] = "%l:% %P on %A, %d %B %Y"; + + fmt[4] = 'M'; /* I *hate* SCCS... */ + (void)time(&t); + (void)strftime(db, sizeof(db), fmt, localtime(&t)); + puts(db); + break; + } + + case '%': + putchr('%'); + break; + } + cp++; + } +} diff --git a/usr.sbin/getty/pathnames.h b/usr.sbin/getty/pathnames.h new file mode 100644 index 0000000..07570e8 --- /dev/null +++ b/usr.sbin/getty/pathnames.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 1989 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)pathnames.h 5.3 (Berkeley) 6/1/90 + */ + +#include + diff --git a/usr.sbin/getty/subr.c b/usr.sbin/getty/subr.c new file mode 100644 index 0000000..8c78892 --- /dev/null +++ b/usr.sbin/getty/subr.c @@ -0,0 +1,578 @@ +/*#pragma debug 25 */ +/*#define BUG(__s) {fprintf(stderr,"%s\n",__s);} */ +#define BUG(__s) +#pragma optimize 31 +#define index strchr + +/* + * Copyright (c) 1983 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)subr.c 5.10 (Berkeley) 2/26/91"; +#endif /* not lint */ + +/* + * Melbourne getty. + */ +#define USE_OLD_TTY +#include +#include /* sleep... */ +#include +#include +#include +#include +#include +#include "gettytab.h" + +extern struct sgttyb tmode; +extern struct tchars tc; +extern struct ltchars ltc; + +/* + * Get a table entry. + */ +gettable(name, buf, area) + char *name, *buf, *area; +{ + register struct gettystrs *sp; + register struct gettynums *np; + register struct gettyflags *fp; + register n; + + hopcount = 0; /* new lookup, start fresh */ + if (getent(buf, name) != 1) + return; + + for (sp = gettystrs; sp->field; sp++) + sp->value = getstr(sp->field, &area); + for (np = gettynums; np->field; np++) { + n = getnum(np->field); + if (n == -1) + np->set = 0; + else { + np->set = 1; + np->value = n; + } + } + for (fp = gettyflags; fp->field; fp++) { + n = getflag(fp->field); + if (n == -1) + fp->set = 0; + else { + fp->set = 1; + fp->value = n ^ fp->invrt; + } + } +} + +gendefaults() +{ + register struct gettystrs *sp; + register struct gettynums *np; + register struct gettyflags *fp; + + for (sp = gettystrs; sp->field; sp++) + if (sp->value) + sp->defalt = sp->value; + for (np = gettynums; np->field; np++) + if (np->set) + np->defalt = np->value; + for (fp = gettyflags; fp->field; fp++) + if (fp->set) + fp->defalt = fp->value; + else + fp->defalt = fp->invrt; +} + +setdefaults() +{ + register struct gettystrs *sp; + register struct gettynums *np; + register struct gettyflags *fp; + + for (sp = gettystrs; sp->field; sp++) + if (!sp->value) + sp->value = sp->defalt; + for (np = gettynums; np->field; np++) + if (!np->set) + np->value = np->defalt; + for (fp = gettyflags; fp->field; fp++) + if (!fp->set) + fp->value = fp->defalt; +} + +static char ** +charnames[] = { + &ER, &KL, &IN, &QU, &XN, &XF, &ET, &BK, + &SU, &DS, &RP, &FL, &WE, &LN, 0 +}; + +static char * +charvars[] = { + &tmode.sg_erase, &tmode.sg_kill, &tc.t_intrc, + &tc.t_quitc, &tc.t_startc, &tc.t_stopc, + &tc.t_eofc, &tc.t_brkc, <c.t_suspc, + <c.t_dsuspc, <c.t_rprntc, <c.t_flushc, + <c.t_werasc, <c.t_lnextc, 0 +}; + +setchars() +{ + register int i; + register char *p; + + for (i = 0; charnames[i]; i++) { + p = *charnames[i]; + if (p && *p) + *charvars[i] = *p; + else + *charvars[i] = '\377'; + } +} + +long +setflags(n) +{ + register long f; + + switch (n) { + case 0: + if (F0set) + return(F0); + break; + case 1: + if (F1set) + return(F1); + break; + default: + if (F2set) + return(F2); + break; + } + + f = 0; + + if (AP) + f |= ANYP; + else if (OP) + f |= ODDP; + else if (EP) + f |= EVENP; + + if (UC) + f |= LCASE; + + if (NL) + f |= CRMOD; + + f |= delaybits(); + + if (n == 1) { /* read mode flags */ + if (RW) + f |= RAW; + else + f |= CBREAK; + return (f); + } + + if (!HT) + f |= XTABS; + + if (n == 0) + return (f); + + if (CB) + f |= CRTBS; + + if (CE) + f |= CRTERA; + + if (CK) + f |= CRTKIL; + + if (PE) + f |= PRTERA; + + if (EC) + f |= ECHO; + + if (XC) + f |= CTLECH; + + if (DX) + f |= DECCTQ; + + return (f); +} + +struct delayval { + unsigned delay; /* delay in ms */ + int bits; +}; + +/* + * below are random guesses, I can't be bothered checking + */ + +struct delayval crdelay[] = { + 1, CR1, + 2, CR2, + 3, CR3, + 83, CR1, + 166, CR2, + 0, CR3, +}; + +struct delayval nldelay[] = { + 1, NL1, /* special, calculated */ + 2, NL2, + 3, NL3, + 100, NL2, + 0, NL3, +}; + +struct delayval bsdelay[] = { + 1, BS1, + 0, 0, +}; + +struct delayval ffdelay[] = { + 1, FF1, + 1750, FF1, + 0, FF1, +}; + +struct delayval tbdelay[] = { + 1, TAB1, + 2, TAB2, + 3, XTABS, /* this is expand tabs */ + 100, TAB1, + 0, TAB2, +}; + +delaybits() +{ + register f; + + f = adelay(CD, crdelay); + f |= adelay(ND, nldelay); + f |= adelay(FD, ffdelay); + f |= adelay(TD, tbdelay); + f |= adelay(BD, bsdelay); + return (f); +} + +adelay(long ms, struct delayval *dp) +{ + if (ms == 0) + return (0); + while (dp->delay && ms > dp->delay) + dp++; + return (dp->bits); +} + +char editedhost[32]; + +edithost(char *pat) +{ + register char *host = HN; + register char *res = editedhost; + + if (pat == NULL) + pat = ""; + while (*pat) { + switch (*pat) { + + case '#': + if (*host) + host++; + break; + + case '@': + if (*host) + *res++ = *host++; + break; + + default: + *res++ = *pat; + break; + + } + if (res == &editedhost[sizeof editedhost - 1]) { + *res = '\0'; + return; + } + pat++; + } + if (*host) + strncpy(res, host, sizeof editedhost - (res - editedhost) - 1); + else + *res = '\0'; + editedhost[sizeof editedhost - 1] = '\0'; +} + +struct speedtab { + int speed; + int uxname; +} speedtab[] = { + 50, B50, + 75, B75, + 110, B110, + 134, B134, + 150, B150, + 200, B200, + 300, B300, + 600, B600, + 1200, B1200, + 1800, B1800, + 2400, B2400, + 4800, B4800, + 9600, B9600, + 19200, EXTA, + 19, EXTA, /* for people who say 19.2K */ + 38400, EXTB, + 38, EXTB, + 7200, EXTB, /* alternative */ + 0 +}; + +speed(long val) +{ + register struct speedtab *sp; + + if (val <= 15) + return (val); + + for (sp = speedtab; sp->speed; sp++) + if (sp->speed == val) + return (sp->uxname); + + return (B300); /* default in impossible cases */ +} + +#ifdef __ORCAC__ + +void addenv(char *vdef) +{ +char *q,*vdef2; +static Set_VarPB setp; +static ExportPB exp; + + if (q = index(vdef,'=')) { + vdef2 = q + 1; + { + char *a,*p; + char sz; + + sz = strlen(vdef2); + p = vdef2 + sz; + for (a=p;a>vdef2;*(a--) = *(--p)); + *a = sz; + sz = q - vdef; + for (a=q;a>vdef;*(a--) = *(--q)); + *a = sz; + } + setp.var_name = vdef; + setp.value = vdef2; + SET_VAR(setp); + exp.name = vdef; + exp.flags = 1; + EXPORT(&exp); + } +} + +void makeenv(void) +{ +#ifdef __ORCAC__ +static char termbuf[128] = "TERM"; +#else +static char termbuf[128] = "TERM="; +#endif +char *p, *q; + + PUSH_VARIABLES(&p); + if (TT && *TT) { + strcat(termbuf, TT); + addenv(termbuf); + } + if (p = EV) { + q = p; + while (q = index(q, ',')) { + *q++ = '\0'; + addenv(p); + p = q; + } + if (*p) + addenv(p); + } +} + +#else + +makeenv(env) + char *env[]; +{ + static char termbuf[128] = "TERM="; + register char *p, *q; + register char **ep; +/* char *index(); */ + + ep = env; + if (TT && *TT) { + strcat(termbuf, TT); + *ep++ = termbuf; + } + if (p = EV) { + q = p; + while (q = index(q, ',')) { + *q++ = '\0'; + *ep++ = p; + p = q; + } + if (*p) + *ep++ = p; + } + *ep = (char *)0; +} + +#endif + +/* + * This speed select mechanism is written for the Develcon DATASWITCH. + * The Develcon sends a string of the form "B{speed}\n" at a predefined + * baud rate. This string indicates the user's actual speed. + * The routine below returns the terminal type mapped from derived speed. + */ +struct portselect { + char *ps_baud; + char *ps_type; +} portspeeds[] = { + { "B110", "std.110" }, + { "B134", "std.134" }, + { "B150", "std.150" }, + { "B300", "std.300" }, + { "B600", "std.600" }, + { "B1200", "std.1200" }, + { "B2400", "std.2400" }, + { "B4800", "std.4800" }, + { "B9600", "std.9600" }, + { "B19200", "std.19200" }, + { 0 } +}; + +char * +portselector() +{ + char c, baud[20], *type = "default"; + register struct portselect *ps; + int len; + + alarm(5*60); + for (len = 0; len < sizeof (baud) - 1; len++) { + if (read(STDIN_FILENO, &c, 1) <= 0) + break; + c &= 0177; + if (c == '\n' || c == '\r') + break; + if (c == 'B') + len = 0; /* in case of leading garbage */ + baud[len] = c; + } + baud[len] = '\0'; + for (ps = portspeeds; ps->ps_baud; ps++) + if (strcmp(ps->ps_baud, baud) == 0) { + type = ps->ps_type; + break; + } + sleep(2); /* wait for connection to complete */ + return (type); +} + +/* + * This auto-baud speed select mechanism is written for the Micom 600 + * portselector. Selection is done by looking at how the character '\r' + * is garbled at the different speeds. + */ +#ifdef SYS_TIME +#include +#endif + +char * +autobaud() +{ + char c, *type = "9600-baud"; +#ifdef SYS_TIME + int null = 0; + int rfds; + struct timeval timeout; + + ioctl(STDIN_FILENO, TIOCFLUSH, &null); + rfds = 1 << 0; + timeout.tv_sec = 5; + timeout.tv_usec = 0; + if (select(32, (fd_set *)&rfds, (fd_set *)NULL, + (fd_set *)NULL, &timeout) <= 0) + return (type); + if (read(STDIN_FILENO, &c, sizeof(char)) != sizeof(char)) + return (type); + timeout.tv_sec = 0; + timeout.tv_usec = 20; + (void) select(32, (fd_set *)NULL, (fd_set *)NULL, + (fd_set *)NULL, &timeout); + ioctl(STDIN_FILENO, TIOCFLUSH, &null); + switch (c & 0377) { + + case 0200: /* 300-baud */ + type = "300-baud"; + break; + + case 0346: /* 1200-baud */ + type = "1200-baud"; + break; + + case 015: /* 2400-baud */ + case 0215: + type = "2400-baud"; + break; + + default: /* 4800-baud */ + type = "4800-baud"; + break; + + case 0377: /* 9600-baud */ + type = "9600-baud"; + break; + } +#endif + return (type); +} diff --git a/usr.sbin/getty/ttydeflts.c b/usr.sbin/getty/ttydeflts.c new file mode 100644 index 0000000..a44abd4 --- /dev/null +++ b/usr.sbin/getty/ttydeflts.c @@ -0,0 +1,70 @@ +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)ttydefaults.c 5.1 (Berkeley) 1/19/91"; +#endif /* not lint */ + +#ifdef TERMIOS +#include +#else +#include +#endif + +set_ttydefaults(fd) + int fd; +{ +#ifdef TERMIOS + struct termios term; + + tcgetattr(fd, &term); + term.c_iflag = TTYDEF_IFLAG; + term.c_oflag = TTYDEF_OFLAG; + term.c_lflag = TTYDEF_LFLAG; + term.c_cflag = TTYDEF_CFLAG; + tcsetattr(fd, TCSAFLUSH, &term); +#else +struct sgttyb sg; +long localmode; + + /* we could do ioctl equiv here */ + gtty(fd,&sg); + sg.sg_flags = ECHO | CRMOD | LCRTERA; + sg.sg_erase = 0x7f; + stty(fd,&sg); + ioctl(fd,TIOCLGET,&localmode); + localmode |= LCRTERA; + localmode |= LCTLECH; + ioctl(fd,TIOCLSET,&localmode); +#endif +} diff --git a/usr.sbin/newuser/README b/usr.sbin/newuser/README new file mode 100644 index 0000000..fb81a88 --- /dev/null +++ b/usr.sbin/newuser/README @@ -0,0 +1,7 @@ +After running the 'install' program, you need to create the files +/var/adm/newuser/newid and /var/adm/newuser/gshrc. The latter is simply +a template gshrc file that all new users will be given. The former is +a file with a single integer (1-5 digits) and *nothing else*. New users +will be assigned the userid found in this file each time newuser is run, +and the userid will be automatically incremented by newuser. So you only +have to set it up once. diff --git a/usr.sbin/newuser/installit b/usr.sbin/newuser/installit new file mode 100644 index 0000000..5ab0c86 --- /dev/null +++ b/usr.sbin/newuser/installit @@ -0,0 +1,9 @@ +echo "Moving files to appropriate places..." +echo +mv -vi newuser /usr/sbin +mv -vi newuserv /usr/sbin +mv -vi newuser.1 /usr/man/man1/ +echo +echo "Make sure the directory /var/adm/newuser exists, and has as" +echo "template 'gshrc' file in it. Also required in that directory" +echo "is the 'newid' file, which holds the next available userid." diff --git a/usr.sbin/newuser/newuser.1 b/usr.sbin/newuser/newuser.1 new file mode 100644 index 0000000..b15e7b1 --- /dev/null +++ b/usr.sbin/newuser/newuser.1 @@ -0,0 +1,52 @@ +.TH NEWUSER 8 +.SH NAME +.nf +newuser - add a new user to the system +newuserv - add a new user to the system, subject to validation +.fi +.LP +.SH DESCRIPTION +This is +.B newuser +for GNO/ME. Its basic intent is +to let people add themselves to the system without requiring the system +administrator to do it all manually. +.LP +.B newuser +will ask for real name, account name, terminal type and password (verifying +the password once) and then create the directory /user/(account name) and +copy a template +.B gshrc +into that directory. Then it will add the user to +.B /etc/passwd +and exit. +.PP +If the +.B -v +(verify) flag is selected, everything is done as normal, except +that the new entry is appended to +.B /var/adm/newuser/newusers +instead of being appended to +.BR /etc/passwd ". " +.LP +.SH FILES +.nf +.BR /var/adm/newuser/newid " -- This file holds the next available" +userID. newuser will increment it as necessary. +.BR /var/adm/newuser/gshrc " -- This is the 'template' gshrc file" +that all new users will get. In addition to this, newuser will append +'set' commands to set $home and $user. +.BR /etc/passwd " -- Not required if you use -v. But what's the point" +in newuser if you don't have it? :) +.BR /user/ " -- Has to exist. This is where the user's home directories" +go. +.fi +.LP +.B newuser +will time out after 60 seconds of operation. +.LP +.SH AUTHOR +.nf +James Brookes +jamesb@cscihp.ecst.csuchico.edu +.fi diff --git a/usr.sbin/newuser/newuser.8 b/usr.sbin/newuser/newuser.8 new file mode 100644 index 0000000..b15e7b1 --- /dev/null +++ b/usr.sbin/newuser/newuser.8 @@ -0,0 +1,52 @@ +.TH NEWUSER 8 +.SH NAME +.nf +newuser - add a new user to the system +newuserv - add a new user to the system, subject to validation +.fi +.LP +.SH DESCRIPTION +This is +.B newuser +for GNO/ME. Its basic intent is +to let people add themselves to the system without requiring the system +administrator to do it all manually. +.LP +.B newuser +will ask for real name, account name, terminal type and password (verifying +the password once) and then create the directory /user/(account name) and +copy a template +.B gshrc +into that directory. Then it will add the user to +.B /etc/passwd +and exit. +.PP +If the +.B -v +(verify) flag is selected, everything is done as normal, except +that the new entry is appended to +.B /var/adm/newuser/newusers +instead of being appended to +.BR /etc/passwd ". " +.LP +.SH FILES +.nf +.BR /var/adm/newuser/newid " -- This file holds the next available" +userID. newuser will increment it as necessary. +.BR /var/adm/newuser/gshrc " -- This is the 'template' gshrc file" +that all new users will get. In addition to this, newuser will append +'set' commands to set $home and $user. +.BR /etc/passwd " -- Not required if you use -v. But what's the point" +in newuser if you don't have it? :) +.BR /user/ " -- Has to exist. This is where the user's home directories" +go. +.fi +.LP +.B newuser +will time out after 60 seconds of operation. +.LP +.SH AUTHOR +.nf +James Brookes +jamesb@cscihp.ecst.csuchico.edu +.fi diff --git a/usr.sbin/newuser/newuser.c b/usr.sbin/newuser/newuser.c new file mode 100644 index 0000000..d1f39f9 --- /dev/null +++ b/usr.sbin/newuser/newuser.c @@ -0,0 +1,340 @@ +/* */ +/* newuser - add a new user to the system, v1.1 -- James Brookes */ +/* */ +/* Changes from 1.0 */ +/* */ +/* * Removed code to add "set $home/$user" stuff to new user's gshrc */ +/* file, per request of Phil Vandry. */ +/* * Added restriction that the new password entered must be greater */ +/* than four characters. */ +/* * Newuser will now try multiple times to open up the /etc/passwd */ +/* file, just as passwd itself does. */ +/* */ +/* Some code borrowed from Eric Shepard's passwd source. */ +/* */ +/* files: /var/adm/newuser/newid */ +/* /var/adm/newuser/newusers */ +/* /var/adm/newuser/gshrc */ +/* /user/ */ +/* */ + +/*#pragma optimize -1 */ +#pragma stacksize 512 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma lint -1 + +char *getpass(char *prompt); +char *crypt(char *key, char *salt); + +void time_out(void); +void makesalt(char *salt, long seed); +int get_next_uid(void); +void getpassword(char *password, char *salt, char *passstring); +int bad_name(char *acct_name); +void myfgets(char *string, int maxchar, FILE *FilePtr); +FILE *smartopen(char *file, char *mode); + +#define NEWID_FILE "/var/adm/newuser/newid" +#define NEWUSERS_FILE "/var/adm/newuser/newusers" +#define NEWGSHRC_FILE "/var/adm/newuser/gshrc" + +#define DEFAULT_GID 2 /* default group ID assigned to new user */ +#define ACCT_NAME_LEN 8 /* max # of chars in account name */ +#define REAL_NAME_LEN 30 /* max # of chars in real name */ +#define TERM_TYPE_LEN 8 /* max # of chars in terminal type */ +#define MAX_TRIES 3 /* max # of trials for opening passwd file */ + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +static char acct_name[ACCT_NAME_LEN+1], + buffer[80], + name[REAL_NAME_LEN+1], + pass1[14], pass2[14], + salt[3], + scratch[256], + term_type[TERM_TYPE_LEN+1]; + +static unsigned char salttab[] = /* table of chars for salt */ + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + +void time_out(void) + + { + printf("\nnewuser timed out after 60 seconds.\n"); + exit(1); + } + +/* Borrowed from Eric's passwd.cc */ + +void makesalt(char *salt, long seed) + + { + int num = 2; + while (--num >= 0) + + { + *salt++ = salttab[seed&0x3f]; + seed >= 6; + } + + } + +int get_next_uid(void) + + { + FILE *FPtr; + int uid; + + FPtr = fopen(NEWID_FILE,"r+"); + fscanf(FPtr,"%d\n",&uid); + rewind(FPtr); + fprintf(FPtr,"%d\n",uid+1); + fclose(FPtr); + + return(uid); + } + +void getpassword(char *password, char *salt, char *passstring) + + { + char *pass, *passcode; + + pass = getpass(passstring); + passcode = crypt(pass,salt); + strcpy(password,passcode); + } + +int bad_name(char *acct_name) + + { + if (!isalpha(*acct_name++)) + return(TRUE); + + while (*acct_name != '\0') + if (!isalnum(*acct_name++)) + return(TRUE); + + return(FALSE); + } + +void myfgets(char *string, int maxchar, FILE *FilePtr) + + { + int last_char; + char *tmp_buf; + + tmp_buf = (char *) malloc (256); + + maxchar++; + fgets(tmp_buf,maxchar,FilePtr); + if (*tmp_buf == 0x00) /* ^D */ + exit(1); + last_char = strlen(tmp_buf)-1; + + /* remove terminating \n if necessary */ + + if ((tmp_buf[last_char] == '\n') || (tmp_buf[last_char] == '\r')) + tmp_buf[last_char] = '\0'; + + strcpy(string,tmp_buf); + fflush(stdin); + free(tmp_buf); + } + +/* try multiple times to open /etc/passwd file */ + +FILE *smartopen(char *file, char *mode) + + { + FILE *FOutPtr; + int i; + + for (i = 0; i < MAX_TRIES; i++) + + { + FOutPtr = fopen(file,mode); + if (FOutPtr == NULL) + sleep(1); + else + break; + } + + return(FOutPtr); + } + +int main (int argc, char **argv) + + { + int validate, uid; + FILE *FInPtr, *FOutPtr; + + struct sgttyb *s; + s = (struct sgttyb *) malloc (sizeof(struct sgttyb)); + + signal(SIGINT,SIG_IGN); + signal(SIGHUP,SIG_IGN); + signal(SIGQUIT,SIG_IGN); + signal(SIGTSTP,SIG_IGN); + signal(SIGALRM,time_out); + + /* Set proper erase character */ + + gtty(STDIN_FILENO,s); + s->sg_erase = 0x7f; + stty(STDIN_FILENO,s); + free(s); + + validate = FALSE; + + if (argc == 2 && !strcmp(argv[1],"-v")) + validate = TRUE; + else if (argc == 1); + else + exit(1); + + /* Make sure all required files exist before going any further */ + + if ((FInPtr = fopen(NEWID_FILE,"r+")) == NULL) + + { + fprintf(stderr,"unable to open %s; exiting.\n",NEWID_FILE); + exit(1); + } + + fclose(FInPtr); + + if ((FInPtr = fopen(NEWGSHRC_FILE,"r+")) == NULL) + + { + fprintf(stderr,"unable to open %s; exiting.\n",NEWGSHRC_FILE); + exit(1); + } + + fclose(FInPtr); + + /* Get information */ + + printf("\nReal Name: "); + myfgets(name,REAL_NAME_LEN,stdin); + + /* Get login name. If the login name is duplicate, prompt for */ + /* a new login name. If the login name would call for the */ + /* creation of a bogus directory, prompt for a new login name. */ + /* Note that I'm using the restrictions of the ProDOS FST, */ + /* since HFS is less restrictive. In other words, the username */ + /* must start with a character and may only contain letters */ + /* and numbers. */ + + while(1) + + { + printf("Login Name: "); + myfgets(acct_name,ACCT_NAME_LEN,stdin); + printf("\n\n(login name: '%s')\n\n",acct_name); + if (getpwnam(acct_name) != NULL) + printf("Duplicate username: please choose another.\n"); + else if (bad_name(acct_name)) + + { + printf("\n** Invalid username: please choose a name comprised of\n"); + printf(" alphanumeric characters which starts with an alphabetic\n"); + printf(" character.\n"); + } + + else + break; + } + + printf("Terminal Type: "); + myfgets(term_type,TERM_TYPE_LEN,stdin); + + /* Get password of > 4 chars, with verification */ + + makesalt(salt, rand()); + while(1) + + { + getpassword(pass1,salt,"Password: "); + getpassword(pass2,salt,"Verify: "); + if (!strcmp(pass1,pass2) && (strlen(pass1) > 4)) + break; + else + printf("*** Failed verification.\n"); + } + + uid = get_next_uid(); /* get and update next free ID# */ + + /* make home directory */ + + sprintf(scratch,"mkdir -s /user/%s",acct_name); + exec("/bin/mkdir",scratch); + sleep(2); + + /* and copy default gshrc to it */ + + sprintf(scratch,"/user/%s/gshrc",acct_name); + FOutPtr = fopen(scratch,"w"); + + FInPtr = fopen(NEWGSHRC_FILE,"r"); + + while(fgets(buffer,80,FInPtr) != NULL) + fputs(buffer,FOutPtr); + fclose(FInPtr); + + /* update default gshrc to have correct $home, $user, and $term */ + +/* Phil asked that this be removed, so... :) + fprintf(FOutPtr,"set home=/user/%s\n",acct_name); + fprintf(FOutPtr,"set user=%s\n",acct_name); +*/ + + fprintf(FOutPtr,"set term=%s\n",term_type); + +/* + fprintf(FOutPtr,"export home user term\n"); +*/ + fprintf(FOutPtr,"export term\n"); + fclose(FOutPtr); + + if (!validate) /* no validation, so append new entry to /etc/passwd */ + + { + FOutPtr = smartopen("/etc/passwd","a"); + if (FOutPtr == NULL) + + { + fprintf(stderr,"Trouble opening /etc/passwd file.\nExiting\n"); + exit(1); + } + + fprintf(FOutPtr,"%s:%s:%d:%d:%s:/user/%s:/bin/gsh\n",acct_name,pass1, + uid,DEFAULT_GID,name,acct_name); + fclose(FOutPtr); + printf("You may now log in.\n"); + } + + else /* validation selected -- so append new entry to NEWUSERS_FILE */ + + { + FOutPtr = fopen(NEWUSERS_FILE,"a"); + fprintf(FOutPtr,"%s:%s:%d:0:%s:/user/%s:/bin/gsh\n",acct_name,pass1, + uid,name,acct_name); + fclose(FOutPtr); + printf("Try back in 24 hours.\n"); + } + + exit(0); + } diff --git a/usr.sbin/newuser/newuserv.c b/usr.sbin/newuser/newuserv.c new file mode 100644 index 0000000..ca0bb8d --- /dev/null +++ b/usr.sbin/newuser/newuserv.c @@ -0,0 +1,16 @@ +#pragma optimize -1 +#pragma stacksize 256 + +/* */ +/* newverify.c - a simple program to launch newuser with the -v option */ +/* */ + +#include +#include +#include + +int main(int argc, char **argv) + + { + execve("/usr/sbin/newuser","newuser -v"); + } diff --git a/usr.sbin/nogetty/nogetty.c b/usr.sbin/nogetty/nogetty.c new file mode 100644 index 0000000..1b5ad73 --- /dev/null +++ b/usr.sbin/nogetty/nogetty.c @@ -0,0 +1,9 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + setenv("user","root"); + setenv("home",":user:root"); + execve("/bin/gsh","gsh"); +}