home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
x
/
volume8
/
xlogin
/
part01
/
xlogin.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-11
|
28KB
|
1,077 lines
/*
* xlogin - X login manager
*
* $Id: xlogin.c,v 2.2 90/07/09 15:41:54 stumpf Exp Locker: stumpf $
*
* Copyright 1989, 1990 Technische Universitaet Muenchen (TUM), Germany
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of TUM not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. TUM makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
*
* Author: Markus Stumpf, Technische Universitaet Muenchen
* (stumpf@lan.informatik.tu-muenchen.de)
*
* $Source: /usr/wiss/stumpf/src/X.V11R4/local/clients/xlogin/RCS/xlogin.c,v $
*
*/
#include <sys/param.h>
#ifdef QUOTA
#include <sys/quota.h>
#endif
#include <sys/stat.h>
#include <errno.h>
#ifdef LASTLOGIN
# include <lastlog.h>
#endif /* LASTLOGIN */
#include <pwd.h>
#include <utmp.h>
/* EMPTY is defined in most <utmp.h> */
#ifndef EMPTY
# define EMPTY ""
#endif
#include <stdio.h>
#ifndef sequent
# include <ttyent.h>
#endif
#include <X11/Xos.h>
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xmu/CharSet.h>
#include "patchlevel.h"
#define XLOGIN_NAME "xlogin"
#define XLOGIN_CLASS "Xlogin"
#define MAXLEN 1024
#define STRCPY(a, b) strncpy(a, b, sizeof(a))
struct passwd *pwd;
struct utmp wtmp;
#ifdef LASTLOGIN
struct lastlog rll;
#endif /* LASTLOGIN */
char path_delimiter[]= "/";
char XTTYname[100];
char HushLog[] = ".hushlogin";
char XLogFile[] = ".Xlogin";
char HushLogin[MAXLEN];
char Lastlog[] = "/usr/adm/lastlog";
#ifndef UTMP_FILE
char Utmp[] = "/etc/utmp";
#else
char Utmp[] = UTMP_FILE;
#endif /* UTMP_FILE */
#ifndef WTMP_FILE
char Wtmp[] = "/usr/adm/wtmp";
#else
char Wtmp[] = WTMP_FILE;
#endif /* WTMP_FILE */
char Motd[] = "/etc/motd";
char NoLogin[] = "/etc/nologin";
char lastltime[100];
char hostname[100];
char dpyname[100];
char versionname[100];
char Myname[255];
char MyRevision[] = "$Revision: 2.2 $";
char MyVersion[] = "2.0";
char DEVname[MAXLEN];
char XLogin[MAXLEN];
int do_login = TRUE;
int do_logout;
int info_atall;
int info_eproclim = FALSE;
int info_eusers = FALSE;
int info_lastlog = FALSE;
int info_motd = FALSE;
int lines_motd = 0;
int lines_nologin = 0;
int info_nolog = FALSE;
int is_hushlogin;
int have_display = TRUE;
extern char *getenv();
extern int errno;
extern int lseek(), exit();
static void ExitMotd();
XtAppContext app_ctxt;
Display *gDisplay;
String display;
Widget toplevel;
XrmOptionDescRec pre_options[] = {
{"-debug", "*debug", XrmoptionNoArg, "True"},
{"-display", "*display", XrmoptionSepArg, ""},
{"-logout", ".logout", XrmoptionNoArg, "True"},
{"-timeOutAction",".timeOutAction",XrmoptionSepArg, "logout"},
{"-version", ".versionOnly", XrmoptionNoArg, "True"}
};
XrmOptionDescRec options[] = {
{"-lines", "lines", XrmoptionSepArg,NULL},
{"-showMOTD", "showMOTD", XrmoptionSepArg,NULL},
{"-showVersion","showVersion", XrmoptionNoArg, "True"},
{"-motdFont", "motdFont", XrmoptionSepArg,NULL}
};
typedef struct {
int lines;
Boolean show_version;
char *show_MOTD;
XFontStruct *motd_font;
} xlog_resourceRec, *xlog_resourcePtr;
typedef struct {
Boolean debug;
String display;
Boolean logout;
Boolean time_out_exit;
Boolean version_only;
} xlog_preresourceRec;
xlog_resourceRec app_resources;
xlog_preresourceRec pre_app_resources;
XtResource resources[] = {
{"lines", "Lines", XtRInt, sizeof(int),
XtOffset(xlog_resourcePtr, lines), XtRString, "0"},
{"showMOTD", "ShowMOTD", XtRString, sizeof(String),
XtOffset(xlog_resourcePtr, show_MOTD), XtRString, (caddr_t) "IfChanged"},
{"showVersion", "ShowVersion", XtRBoolean, sizeof(Boolean),
XtOffset(xlog_resourcePtr, show_version), XtRImmediate, (caddr_t)False},
{"motdFont", XtCFont, XtRFontStruct, sizeof(XFontStruct *),
XtOffset(xlog_resourcePtr, motd_font), XtRString,
"-misc-fixed-medium-r-normal--*-120-*-*-c-*-iso8859-1"}
};
XtCallbackRec callbacks[] =
{ {ExitMotd, NULL}, {NULL, NULL} };
Debug (fmt, arg1, arg2, arg3, arg4, arg5)
char *fmt;
int arg1, arg2, arg3, arg4, arg5;
{
if (pre_app_resources.debug) {
fprintf(stderr,"Debug: ");
fprintf (stderr,fmt, arg1, arg2, arg3, arg4, arg5);
fprintf(stderr,"\n");
fflush(stderr);
}
}
/*
* This routine is called before exit; it closes the display
* and frees all resources
*/
void CloseXDisplay()
{
Debug("Closing X Display");
XtDestroyWidget(toplevel);
XtDestroyApplicationContext(app_ctxt);
}
/*
* This is the routine that is called on press of the
* endbutton; exits program with status 0, if login permitted,
* with status 1 otherwise
*/
static void ExitMotd()
{
CloseXDisplay();
Debug("ExitMotd(): status=%d ", !do_login);
exit(!do_login);
}
/*
* This is the routine that's called when the timeout has
* expired.
*/
static void motdTimeOver(c_data, id)
XtPointer c_data;
XtIntervalId *id;
{
Debug("Timeout has expired");
do_login = !pre_app_resources.time_out_exit;
ExitMotd();
}
/*
* This procedure is called to initialize the passwd struct,
* the paths to the various files and the utmp struct.
*/
void Init()
{
char *user, *home;
char *number, *tmp;
int home_len;
Debug("Init()");
/*
* get the user from the environment
*/
if ((user = getenv("USER")) == NULL) {
fprintf(stderr,"%s: cannot getenv(\"USER\") \n", Myname);
exit(1);
}
Debug("Init(): user=%s ", user);
/*
* get the display from the environment,
* if we hadn't it yet from the options
*/
if (pre_app_resources.display == (String) NULL) {
if ((display = getenv("DISPLAY")) == NULL) {
fprintf(stderr,"%s: cannot getenv(\"DISPLAY\") \n",
Myname);
exit(1);
}
} else display = pre_app_resources.display;
Debug("Init(): display=%s ", display);
/*
* get the passwd entry of the user
*/
if ((pwd = getpwnam(user)) == NULL) {
endpwent();
fprintf(stderr,"%s: cannot getpwnam(%s) \n", Myname, user);
exit(1);
}
endpwent();
/*
* set the path to the users home directory
*/
if ((home = getenv("HOME")) == NULL) {
home = pwd->pw_dir;
}
Debug("Init(): home=%s ", home);
/*
* build up the variables pointing to the files we want
* to use and check, whether we reserved enough space
* otherwise exit
*/
home_len = strlen(home) + 1; /* pathname + delimiter */
if (home_len >= MAXLEN) {
fprintf(stderr, "%s: pathname length overflow \n", Myname);
exit(1);
}
STRCPY(HushLogin, home); strcat(HushLogin, path_delimiter);
STRCPY(XLogin, home); strcat(XLogin, path_delimiter);
if (home_len + strlen(HushLog) > MAXLEN) {
fprintf(stderr, "%s: pathname length overflow \n", Myname);
exit(1);
}
if (home_len + strlen(XLogFile) > MAXLEN) {
fprintf(stderr, "%s: pathname length overflow \n", Myname);
exit(1);
}
strncat(HushLogin, HushLog, MAXLEN-strlen(HushLogin));
strncat(XLogin, XLogFile, MAXLEN-strlen(XLogFile));
/*
* set up XTTYname from display information
*/
STRCPY(dpyname, display);
if (number = index(dpyname, ':')) {
*number++ = '\0';
if (tmp = index(dpyname, '.')) *tmp = '\0';
gethostname(hostname, sizeof(hostname));
if (tmp = index(hostname, '.')) *tmp = '\0';
if (strcmp(dpyname, hostname) == 0 ||
strcmp(dpyname, "localhost") == 0 ||
strcmp(dpyname, "unix") == 0 ||
strcmp(dpyname, "") == 0 ) {
if (tmp = index(number, '.')) *tmp = '\0';
STRCPY(XTTYname, "X");
strncat(XTTYname, number,
sizeof(XTTYname)-strlen(XTTYname));
}
else
STRCPY(XTTYname, dpyname);
}
else
STRCPY(XTTYname, "Xlogin");
if (*display == ':') {
#ifdef HOSTNAME
STRCPY(dpyname, hostname);
strncat(dpyname, display, sizeof(dpyname)-strlen(dpyname));
#else
*dpyname = '\0';
#endif
} else {
STRCPY(dpyname, display);
}
Debug("Init(): XTTYName=%s, display=%s ", XTTYname, dpyname);
/*
* set up the utmp struct for the wtmp file
*/
STRCPY(wtmp.ut_name, pwd->pw_name);
STRCPY(wtmp.ut_host, dpyname);
STRCPY(wtmp.ut_line, XTTYname);
time((long *) &wtmp.ut_time);
/*
* check if $HOME/.hushlogin exists and set the
* appropriate flag
*/
is_hushlogin = (access(HushLogin, F_OK) == 0);
}
/*
* this procedure checks, whether logins are permitted
* and sets the appropriate flags
*/
void CheckNologin()
{
int c;
FILE *fp;
Debug("CheckNologin()");
if (access(NoLogin, F_OK) == 0) {
Debug("CheckNologin(): file %s found. ", NoLogin);
/*
* deny login only, if user not root
*/
do_login = FALSE | (pwd->pw_uid == 0);
info_nolog = TRUE;
/*
* count lines in nologin to determine size of Text widget
*/
lines_nologin = 0;
if ((fp=fopen(NoLogin, "r")) == NULL) {
return;
}
while ((c = getc(fp)) != EOF)
if (c == '\n')
++lines_nologin;
fclose(fp);
Debug("CheckNologin(): %s has %d lines. ", NoLogin, lines_nologin);
} else {
Debug("CheckNologin(): file %s not found. ", NoLogin);
}
}
#ifdef QUOTA
/*
* deny login because of bad quota ?
*/
void CheckQuota()
{
int retcode;
Debug("CheckQuota()");
Debug("CheckQuota(): userid=%d ", pwd->pw_uid);
errno = 0;
quota(Q_SETUID, 0, 0, (caddr_t) 0);
if ((retcode=quota(Q_SETUID, pwd->pw_uid, 0, (caddr_t) 0) < 0)
&& (errno != EINVAL)) {
if (errno == EUSERS) {
do_login = FALSE;
info_eusers = TRUE;
} else {
if (errno = EPROCLIM) {
do_login = FALSE;
info_eproclim = TRUE;
}
}
}
Debug("CheckQuota(): quota returned %d, errno=%d", retcode, errno);
}
#endif
/*
* check if motd file exists and whether it is newer than
* the lastlogin-time or if that is 0, if it is newer than
* a possibly existing file $HOME/.Xlogin
* Then check it with the "showMOTD" resource
*/
void CheckMotd()
{
struct stat buf1, buf2;
int c;
FILE *fp;
info_motd = TRUE;
lines_motd = 0;
Debug("CheckMotd()");
if (stat(Motd, &buf1) != 0) {
info_motd = FALSE;
Debug("CheckMotd(): No %s file found", Motd);
return;
} else {
/*
* count lines in motd to determine size of Text widget
*/
if ((fp=fopen(Motd, "r")) == NULL) {
Debug("CheckMotd(): %s is unreadable", Motd);
info_motd = FALSE;
return;
}
while ((c = getc(fp)) != EOF)
if (c == '\n')
++lines_motd;
fclose(fp);
Debug("CheckMotd(): %s has %d lines.", Motd, lines_motd);
}
#ifdef LASTLOGIN
if (rll.ll_time != 0) {
Debug("CheckMotd(): lastlogin time found");
info_motd = (rll.ll_time < buf1.st_mtime);
} else
#endif /* LASTLOGIN */
{
if (stat(XLogin, &buf2) == 0) {
Debug("CheckMotd(): file %s found", XLogin);
utime(XLogin, NULL);
info_motd = (buf2.st_mtime < buf1.st_mtime);
} else {
Debug("CheckMotd(): no %s file found", XLogin);
info_motd = TRUE;
}
}
}
/*
* Return the number of the slot in the utmp file
* Definition is the line number in the /etc/ttys file.
*/
#ifndef sequent
int xttyslot()
{
register struct ttyent *ty;
register int s;
setttyent();
s = 0;
while ((ty = getttyent()) != NULL) {
s++;
if (strcmp(ty->ty_name, XTTYname) == 0) {
endttyent();
return (s);
}
}
endttyent();
return (0);
}
#else
char *getttys();
static char ttys[] = "/etc/ttys";
static char *_b, *_p;
static int _c;
int xttyslot()
{
register int s, tf;
register char *tp;
char b[1024];
if ((tf = open(ttys, 0)) < 0)
return(0);
_p = _b = b;
_c = 0;
s = 0;
while (tp = getttys(tf)) {
s++;
if (strcmp(XTTYname, tp)==0) {
close(tf);
return(s);
}
}
close(tf);
return(0);
}
static char *
getttys(f) {
static char line[32];
register char *lp;
lp = line;
for (;;) {
if (--_c < 0)
if ((_c = read(f, _p = _b, 1024)) <= 0)
return(NULL);
else
--_c;
*lp = *_p++;
if (*lp =='\n') {
*lp = '\0';
return(line + 2);
}
if (lp >= &line[sizeof line])
return(line + 2);
lp++;
}
}
#endif
/*
* this procedure writes the wtmp entry
*/
void WriteWtmp()
{
struct stat buf;
int wtmpfd, utmpfd;
int xtty;
Debug("WriteWtmp()");
xtty = xttyslot();
Debug("WriteWtmp(): xttyslot=%d", xtty);
if (xtty > 0 && (utmpfd = open(Utmp, O_WRONLY)) >= 0) {
Debug("WriteWtmp(): reading utmp file");
lseek(utmpfd, (long)(xtty*sizeof(wtmp)), 0);
write(utmpfd, (char *)&wtmp, sizeof(wtmp));
close(utmpfd);
if (strcmp(wtmp.ut_name, EMPTY) != 0) {
STRCPY(DEVname, "/dev/");
strncat(DEVname, XTTYname,
sizeof(DEVname)-strlen(DEVname));
if (stat(DEVname, &buf) == 0) {
Debug("WriteWtmp(): uptiming %s", DEVname);
utime(DEVname, NULL);
}
}
}
/*
* write only if file exists, don't create it
*/
if ((wtmpfd = open(Wtmp, O_WRONLY|O_APPEND)) >= 0) {
Debug("WriteWtmp(): writing wtmp file");
write(wtmpfd, (char *) &wtmp, sizeof(wtmp));
close(wtmpfd);
}
Debug("WriteWtmp(): leaving ...");
}
#ifdef LASTLOGIN
/*
* this procedure reads from and writes to the
* lastlogin file. If none exists, it will not be created.
*/
void DoLastLogin()
{
struct lastlog wll;
int llfd; /* Lastlog file descriptor */
Debug("DoLastLogin()");
rll.ll_time = 0;
STRCPY(lastltime, "Last Login: ");
if ((llfd = open(Lastlog, O_RDONLY)) >= 0) {
/*
* get time of last login, if any
*/
Debug("DoLastLogin(): reading lastlog file");
lseek(llfd, (long) pwd->pw_uid * sizeof(struct lastlog), 0);
if (read(llfd, (char *) &rll, sizeof(rll)) == sizeof(rll)
&& (rll.ll_time != 0)) {
strncat(lastltime, ctime((long *) &rll.ll_time), 24);
if (strcmp(rll.ll_host, "") != 0) {
strcat(lastltime, " from ");
strncat(lastltime, rll.ll_host, 16);
}
info_lastlog = !is_hushlogin;
}
close(llfd);
/*
* write new last login time
*/
if ((llfd = open(Lastlog, O_WRONLY)) >= 0) {
Debug("DoLastLogin(): writing lastlog file");
lseek(llfd, (long) pwd->pw_uid * sizeof(struct lastlog), 0);
wll.ll_time = wtmp.ut_time;
STRCPY(wll.ll_line, XTTYname);
STRCPY(wll.ll_host, wtmp.ut_host);
write(llfd, (char *) &wll, sizeof(wll));
close(llfd);
}
}
Debug("DoLastLogin(): leaving ...");
}
#endif /* LASTLOGIN */
/*
* in this procedure I do a kind of a prescan of some commandline options,
* to avoid connecting to the X server, if not necessary at all.
*/
LoadPreResources(argc, argv)
int *argc;
char *argv[];
#define RESLEN 255
{
char *str_type;
XrmValue xrm_value;
XrmDatabase PreResDB;
char res[RESLEN];
XrmInitialize();
/*
* Need an empty database; that's a good trick
*/
PreResDB = XrmGetStringDatabase("");
XrmParseCommand(&PreResDB, pre_options, XtNumber(pre_options),
XLOGIN_NAME, argc, argv);
STRCPY(res, XLOGIN_NAME); strncat(res, ".debug", RESLEN-strlen(res));
if (XrmGetResource(PreResDB, res, "", &str_type, &xrm_value)) {
pre_app_resources.debug =
(XmuCompareISOLatin1(xrm_value.addr, "true") == 0);
} else pre_app_resources.debug = False;
STRCPY(res, XLOGIN_NAME); strncat(res, ".display", RESLEN-strlen(res));
if (XrmGetResource(PreResDB, res, "", &str_type, &xrm_value)) {
pre_app_resources.display = XtNewString(xrm_value.addr);
} else pre_app_resources.display = (String) NULL;
STRCPY(res, XLOGIN_NAME); strncat(res, ".logout", RESLEN-strlen(res));
if (XrmGetResource(PreResDB, res, "", &str_type, &xrm_value)) {
pre_app_resources.logout =
(XmuCompareISOLatin1(xrm_value.addr, "true") ==0);
} else pre_app_resources.logout = False;
STRCPY(res, XLOGIN_NAME); strncat(res, ".timeOutAction", RESLEN-strlen(res));
if (XrmGetResource(PreResDB, res, "", &str_type, &xrm_value)) {
pre_app_resources.time_out_exit =
(XmuCompareISOLatin1(xrm_value.addr, "logout") == 0);
/* set to True equiv. to logout */
} else pre_app_resources.time_out_exit = True;
STRCPY(res, XLOGIN_NAME); strncat(res, ".versionOnly", RESLEN-strlen(res));
if (XrmGetResource(PreResDB, res, "", &str_type, &xrm_value)) {
pre_app_resources.version_only =
(XmuCompareISOLatin1(xrm_value.addr, "true") ==0);
} else pre_app_resources.version_only = False;
XrmDestroyDatabase(PreResDB);
Debug("LoadPreResources(): display=%s", pre_app_resources.display);
Debug("LoadPreResources(): logout=%d", pre_app_resources.logout);
Debug("LoadPreResources(): timeOutAction=%d", pre_app_resources.time_out_exit);
Debug("LoadPreResources(): versionOnly=%d", pre_app_resources.version_only);
Debug("LoadPreResources(): leaving ...");
}
/*
* this procedure initializes the display and parses
* the command line options
*/
void InitXDisplay(argc, argv)
int *argc;
char *argv[];
{
Debug("InitXDisplay()");
Debug("InitXDisplay(): argc=%d", *argc);
XtToolkitInitialize();
app_ctxt = XtCreateApplicationContext();
gDisplay = XtOpenDisplay(app_ctxt, display, XLOGIN_NAME, XLOGIN_CLASS,
options, XtNumber(options), argc, argv);
if (gDisplay == (Display *) NULL) {
fprintf(stderr, "%s: WARNING! Cannot open display \"%s\" \n",
Myname, display);
XtDestroyApplicationContext(app_ctxt);
have_display = FALSE;
return;
}
toplevel = XtAppCreateShell(XLOGIN_NAME, XLOGIN_CLASS,
applicationShellWidgetClass, gDisplay, NULL, 0);
XtGetApplicationResources(toplevel, &app_resources, resources,
XtNumber(resources), NULL, 0);
Debug("InitXDisplay(): showVersion=%d",app_resources.show_version);
}
/*
* this procedure does all the display stuff:
* defining, creating and starting widgets
*/
void DoXDisplay()
{
#define LABELLEN 255
Widget form, endbutton, logininfo, motd, version_w,
quota_w, motd_label;
Widget queue;
Arg args[20];
Dimension width, motd_height, nolog_height,
formwidth, formheight,
fnt_width, fnt_height;
Position dpywidth, dpyheight;
char motd_label_text[LABELLEN],
nolog_info_text[LABELLEN],
nolog_label_text[LABELLEN];
int timeout_mult;
static Arg label_args[] = {
{XtNresize, (XtArgVal) True},
{XtNjustify, (XtArgVal) XtJustifyCenter},
{XtNborderWidth, (XtArgVal) 0},
{XtNwidth, (XtArgVal) 0},
{XtNfromVert, (XtArgVal) NULL},
{XtNlabel, (XtArgVal) NULL}
};
static Arg text_args[] = {
{XtNstring, (XtArgVal) NULL},
{XtNfromVert, (XtArgVal) NULL},
{XtNwidth, (XtArgVal) 0},
{XtNheight, (XtArgVal) 0},
{XtNfont, (XtArgVal) NULL},
{XtNscrollHorizontal, (XtArgVal) XawtextScrollWhenNeeded},
{XtNscrollVertical, (XtArgVal) XawtextScrollWhenNeeded},
{XtNeditType, (XtArgVal) XawtextRead},
{XtNtype, (XtArgVal) XawAsciiFile},
{XtNdisplayCaret, (XtArgVal) False}
};
Debug("DoXDisplay()");
timeout_mult = 0;
motd = (Widget) NULL;
XtSetArg(args[0], XtNresizable, True);
XtSetArg(args[1], XtNresize, True);
form = XtCreateManagedWidget("form", formWidgetClass, toplevel,
(ArgList) args, 2);
XtSetArg(args[0], XtNresize, True);
XtSetArg(args[1], XtNallowShellResize, True);
XtSetValues(toplevel, args, 2);
/* find the max width and height of the font */
fnt_width = app_resources.motd_font->max_bounds.width;
fnt_height = app_resources.motd_font->ascent + app_resources.motd_font->descent;
Debug("DoXDisplay(): Fontinfo: width=%d, height=%d", fnt_width, fnt_height);
/*
* plan for 80 columns and match the number of lines in motd
* allow for default border width of 1 at both edges
* allow 1 line for sometimes wrong font infos
* add 20 pxl to width for scrollbar if lines_motd > app_resources.lines
*/
Debug("DoXDisplay(): lines set from resources=%d", app_resources.lines);
if ((app_resources.lines == 0) | (app_resources.lines > lines_motd+1))
motd_height = fnt_height * (lines_motd + 1);
else motd_height = fnt_height * (app_resources.lines + 1);
if ((app_resources.lines == 0) | (app_resources.lines > lines_nologin+1))
nolog_height = fnt_height * (lines_nologin + 1);
else nolog_height = fnt_height * (app_resources.lines + 1);
width = fnt_width * 80 + 2;
label_args[3].value = (XtArgVal) width;
text_args[2].value = (XtArgVal) width;
text_args[4].value = (XtArgVal) app_resources.motd_font;
queue = (Widget) NULL;
if (app_resources.show_version) {
label_args[5].value = (XtArgVal) versionname;
queue=version_w = XtCreateManagedWidget("version", labelWidgetClass,
form, label_args, XtNumber(label_args));
}
label_args[4].value = (XtArgVal) queue;
#ifdef LASTLOGIN
if (info_lastlog) {
label_args[5].value = (XtArgVal) lastltime;
} else
#endif /* LASTLOGIN */
if (do_login) {
STRCPY(nolog_info_text,
"No information available on time of last login");
label_args[5].value = (XtArgVal) nolog_info_text;
} else {
STRCPY(nolog_info_text,
"Sorry, no login permitted");
label_args[5].value = (XtArgVal) nolog_info_text;
}
queue=logininfo = XtCreateManagedWidget("loginInfo", labelWidgetClass,
form, label_args, XtNumber(label_args));
if (do_login | info_nolog) {
if (info_motd) {
STRCPY(motd_label_text,"Message Of The Day follows:");
label_args[5].value = (XtArgVal) motd_label_text;
} else if (info_nolog) {
STRCPY(nolog_label_text, "Text in file ");
strncat(nolog_label_text, NoLogin,
LABELLEN-strlen(nolog_label_text));
strncat(nolog_label_text, " follows:",
LABELLEN-strlen(nolog_label_text));
label_args[5].value = (XtArgVal) nolog_label_text;
} else {
STRCPY(motd_label_text, "Nothing changed in ");
strncat(motd_label_text, Motd,
LABELLEN-strlen(motd_label_text));
strncat(motd_label_text, " since your last login",
LABELLEN-strlen(motd_label_text));
label_args[5].value = (XtArgVal) motd_label_text;
}
label_args[4].value = (XtArgVal) queue;
queue=motd_label = XtCreateManagedWidget("motdLabel", labelWidgetClass,
form, (ArgList) label_args, 6);
}
#ifdef QUOTA
if (info_eusers | info_eproclim) {
if (info_eproclim) {
label_args[5].value = (XtArgVal)
"You have too many processes running.";
} else {
label_args[5].value = (XtArgVal)
"Too many users already logged in. Try again later";
}
label_args[4].value = (XtArgVal) queue;
queue=quota_w = XtCreateManagedWidget("quotaInfo", labelWidgetClass,
form, (ArgList) label_args, 6);
}
#endif /* QUOTA */
if (info_nolog) {
timeout_mult = lines_nologin;
XtSetArg(text_args[0], XtNstring, NoLogin);
XtSetArg(text_args[1], XtNfromVert, queue);
XtSetArg(text_args[3], XtNheight, nolog_height);
queue=motd = XtCreateManagedWidget("motd", asciiTextWidgetClass,
form, (ArgList) text_args, XtNumber(text_args));
Debug("Uninstalling Translations for motd widget ...");
XtUninstallTranslations(motd);
} else {
if (info_motd) {
timeout_mult = lines_motd;
XtSetArg(text_args[0], XtNstring, Motd);
XtSetArg(text_args[1], XtNfromVert, queue);
XtSetArg(text_args[3], XtNheight, motd_height);
queue=motd = XtCreateManagedWidget("motd", asciiTextWidgetClass,
form, (ArgList) text_args, XtNumber(text_args));
Debug("Uninstalling Translations for motd widget ...");
XtUninstallTranslations(motd);
}
}
XtSetArg(args[0], XtNcallback, callbacks);
XtSetArg(args[1], XtNjustify, XtJustifyCenter);
XtSetArg(args[2], XtNresize, True);
XtSetArg(args[3], XtNresizable, False);
XtSetArg(args[4], XtNwidth, width);
XtSetArg(args[5], XtNfromVert, queue);
XtSetArg(args[6], XtNborderWidth, (Dimension) 2);
XtSetArg(args[7], XtNhighlightThickness, (Dimension) 2);
XtSetArg(args[8], XtNinternalHeight, (Dimension) 3);
XtSetArg(args[9], XtNinternalWidth, (Dimension) 3);
XtSetArg(args[10],XtNlabel, "Click here to continue");
endbutton = XtCreateManagedWidget("endbutton", commandWidgetClass,
form, (ArgList) args, 11);
Debug("Installing Accelerators for form widget");
XtInstallAccelerators(form, endbutton);
/*
* Get the size of the screen.
* Want the window to be centered.
*/
dpywidth = DisplayWidth(XtDisplay(form), DefaultScreen(XtDisplay(form)));
dpyheight = DisplayHeight(XtDisplay(form), DefaultScreen(XtDisplay(form)));
/*
* Don't map, but realize it, to get the size of the window
*/
XtSetMappedWhenManaged(toplevel, False);
XtRealizeWidget(toplevel);
while (!XtIsRealized(form))
formwidth=2;
/*
* Get the size of the window
*/
XtSetArg(args[0], XtNwidth, &formwidth);
XtSetArg(args[1], XtNheight, &formheight);
XtGetValues(form, args, 2);
/*
* Place the window centered on the screen.
* allow 5 pixels distance to top and bottom
*/
if ((dpyheight < formheight) && (motd != NULL)) {
int dpy_offest = 5;
Dimension motd_width;
Debug("DoXDisplay(): New layout for motd ...");
dpyheight -= 2*dpy_offest;
Debug("DoXDislay(): motd_height was %d", motd_height);
XtSetArg(args[0], XtNheight, &motd_height);
XtSetArg(args[1], XtNwidth, &motd_width);
XtGetValues(motd, args, 2);
motd_height -= (formheight - dpyheight);
/*
* set new height of motd-widget and allow
* 20 pixels for scrollbar
*/
XtSetArg(args[0], XtNheight, motd_height);
XtSetArg(args[1], XtNwidth, motd_width + 20);
XtSetValues(motd, args, 2);
XtSetArg(args[0], XtNheight, dpyheight);
XtSetValues(form, args, 1);
XawFormDoLayout(form, True);
XtMoveWidget(toplevel, (Position) (dpywidth-formwidth)/2,
(Position) dpy_offest);
} else {
XtMoveWidget(toplevel, (Position) (dpywidth-formwidth)/2,
(Position) (dpyheight-formheight)/2);
}
/*
* Now map the window to get it visible
*/
XtSetMappedWhenManaged(toplevel, True);
XtMapWidget(toplevel);
/*
* Warp the pointer into the button-click window
*/
XWarpPointer(XtDisplay(toplevel), (Window) NULL, XtWindow(endbutton),
0, 0, 0, 0, width/2, 3);
Debug("DoXDisplay(): timeout multiplicator=%d", timeout_mult);
/*
* add timeout, so user get's kicked off, if he's not
* behind the the display
*/
if (!info_motd || pre_app_resources.time_out_exit) {
XtAppAddTimeOut(app_ctxt,
(unsigned long) (timeout_mult+30)*1000,
motdTimeOver, (XtPointer) NULL);
Debug("DoXDisplay(): TimeOut added.");
}
Debug("DoXDisplay(): starting XtAppMainLoop()");
XtAppMainLoop(app_ctxt);
}
main(argc, argv)
int argc;
char *argv[];
{
STRCPY(Myname, argv[0]);
MyRevision[0] = ' ';
MyRevision[strlen(MyRevision)-1] = '\0';
sprintf(versionname,"%s- version %s patchlevel %d \0",
MyRevision, MyVersion, PATCHLEVEL);
LoadPreResources(&argc, argv);
if (pre_app_resources.version_only) {
fprintf(stderr,"%s:%s \n", Myname, versionname);
exit(1);
}
do_logout = pre_app_resources.logout;
if ((argc > 1) && do_logout) {
fprintf(stderr,"%s: unknown option %s \n", Myname,
argv[1]);
exit(1);
}
Init();
Debug("main(): after Init()");
if (do_logout) {
Debug("main(): logging out ...");
STRCPY(wtmp.ut_name, EMPTY);
WriteWtmp();
exit(0);
}
InitXDisplay(&argc, argv);
Debug("main(): after InitXDisplay()");
if ((argc > 1) & have_display) {
fprintf(stderr,"%s: unknown option %s \n", Myname,
argv[1]);
CloseXDisplay();
exit(1);
}
do_login = !do_logout;
CheckNologin();
#ifdef QUOTA
CheckQuota();
#endif
if (do_login) {
WriteWtmp();
#ifdef LASTLOGIN
DoLastLogin();
#endif /* LASTLOGIN */
CheckMotd();
}
if (have_display) {
Debug("main(): showMOTD=%s", app_resources.show_MOTD);
info_motd |= (XmuCompareISOLatin1(app_resources.show_MOTD,
"always") == 0);
}
/*
* display motd only if no .hushlogin exists
* and /etc/motd has more than 0 lines!
*/
info_motd = info_motd && !is_hushlogin && (lines_motd != 0);
info_atall = info_lastlog | info_motd | info_eusers
| info_eproclim | info_nolog;
if (info_atall & have_display) {
DoXDisplay();
}
}