546N/A/*
546N/A * Copyright (c) 1988-91 by Patrick J. Naughton.
546N/A *
546N/A * Permission to use, copy, modify, and distribute this software and its
546N/A * documentation for any purpose and without fee is hereby granted,
546N/A * provided that the above copyright notice appear in all copies and that
546N/A * both that copyright notice and this permission notice appear in
546N/A * supporting documentation.
546N/A *
546N/A * This file is provided AS IS with no warranties of any kind. The author
546N/A * shall have no liability with respect to the infringement of copyrights,
546N/A * trade secrets or any patents by this file or any part thereof. In no
546N/A * event will the author be liable for any lost revenue or profits or
546N/A * other special, indirect and consequential damages.
546N/A */
546N/A
546N/A/*
1233N/A * Copyright (c) 1990, 2011, Oracle and/or its affiliates. All rights reserved.
546N/A *
546N/A * Permission is hereby granted, free of charge, to any person obtaining a
919N/A * copy of this software and associated documentation files (the "Software"),
919N/A * to deal in the Software without restriction, including without limitation
919N/A * the rights to use, copy, modify, merge, publish, distribute, sublicense,
919N/A * and/or sell copies of the Software, and to permit persons to whom the
919N/A * Software is furnished to do so, subject to the following conditions:
546N/A *
919N/A * The above copyright notice and this permission notice (including the next
919N/A * paragraph) shall be included in all copies or substantial portions of the
919N/A * Software.
546N/A *
919N/A * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
919N/A * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
919N/A * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
919N/A * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
919N/A * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
919N/A * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
919N/A * DEALINGS IN THE SOFTWARE.
546N/A */
546N/A/*-
546N/A * resource.c - resource management for xlock, the X Window System lockscreen.
546N/A *
546N/A * Revision History:
546N/A * 24-Jun-91: changed name to username.
546N/A * 06-Jun-91: Added flame mode.
546N/A * 24-May-91: Added -name and -usefirst and -resources.
546N/A * 16-May-91: Added random mode and pyro mode.
546N/A * 26-Mar-91: CheckResources: delay must be >= 0.
546N/A * 29-Oct-90: Added #include <ctype.h> for missing isupper() on some OS revs.
546N/A * moved -mode option, reordered Xrm database evaluation.
546N/A * 28-Oct-90: Added text strings.
546N/A * 26-Oct-90: Fix bug in mode specific options.
546N/A * 31-Jul-90: Fix ':' handling in parsefilepath
546N/A * 07-Jul-90: Created from resource work in xlock.c
546N/A *
546N/A */
546N/A#include <stdio.h>
546N/A#include "xlock.h"
546N/A#include <netdb.h>
546N/A#include <math.h>
546N/A#include <ctype.h>
546N/A#include <sys/socket.h>
546N/A#include <stdlib.h>
546N/A#include <X11/Xresource.h>
546N/A
546N/A
546N/Atypedef struct {
1233N/A const char *cmdline_arg;
546N/A void (*lp_init) ();
546N/A void (*lp_callback) ();
546N/A int def_delay;
546N/A int def_batchcount;
546N/A float def_saturation;
1233N/A const char *desc;
546N/A} LockStruct;
546N/A
1233N/Astatic const char randomstring[] = "random";
546N/A
546N/Astatic LockStruct LockProcs[] = {
546N/A {"hop", inithop, drawhop, 0, 1000, 1.0, "Hopalong iterated fractals"},
546N/A {"qix", initqix, drawqix, 30000, 64, 1.0, "Spinning lines a la Qix(tm)"},
546N/A {"image", initimage, drawimage, 2000000, 8, 0.3, "Random bouncing image"},
546N/A {"life", initlife, drawlife, 1000000, 100, 1.0, "Conway's game of Life"},
546N/A {"swarm", initswarm, drawswarm, 10000, 100, 1.0, "Swarm of bees"},
546N/A {"rotor", initrotor, drawrotor, 10000, 4, 0.4, "Tom's Roto-Rooter"},
546N/A {"pyro", initpyro, drawpyro, 15000, 40, 1.0, "Fireworks"},
546N/A {"flame", initflame, drawflame, 10000, 20, 1.0, "Flame Fractals"},
546N/A {"blank", initblank, drawblank, 5000000, 1, 1.0, "Blank screen"},
546N/A {randomstring, NULL, NULL, 0, 0, 0.0, "Random mode"},
546N/A};
546N/A#define NUMPROCS (sizeof LockProcs / sizeof LockProcs[0])
546N/A
546N/A#ifndef MAXHOSTNAMELEN
546N/A#define MAXHOSTNAMELEN 64 /* SunOS 3.5 does not define this */
546N/A#endif
546N/A
546N/A#ifdef X_NOT_STDC_ENV
546N/Aextern char *getenv();
546N/A#endif
546N/Aextern char *inet_ntoa();
546N/A
546N/A#ifndef DEF_FILESEARCHPATH
546N/A#define DEF_FILESEARCHPATH "/usr/lib/X11/%T/%N%S"
546N/A#endif
546N/A#define DEF_DISPLAY ":0"
546N/A#define DEF_MODE "life"
546N/A#define DEF_FONT "-b&h-lucida-medium-r-normal-sans-24-*-*-*-*-*-iso8859-1"
546N/A#define DEF_BG "White"
546N/A#define DEF_FG "Black"
546N/A#define DEF_NAME "Name: "
546N/A#define DEF_PASS "Password: "
546N/A#define DEF_INFO "Enter password to unlock; select icon to lock."
546N/A#define DEF_VALID "Validating login..."
546N/A#define DEF_INVALID "Invalid login."
546N/A#define DEF_TIMEOUT "30" /* secs till password entry times out */
546N/A#define DEF_BC "100" /* vectors (or whatever) per batch */
546N/A#define DEF_DELAY "200000"/* microseconds between batches */
546N/A#define DEF_NICE "10" /* xlock process nicelevel */
546N/A#define DEF_SAT "1.0" /* color ramp saturation 0->1 */
546N/A#define DEF_CLASSNAME "XLock"
546N/A
546N/Astatic char *classname;
546N/Astatic char modename[BUFSIZ]; /* BUFSIZ is 1024, defined in stdio.h */
546N/Astatic char modeclass[BUFSIZ];
546N/A
546N/Astatic XrmOptionDescRec genTable[] = {
546N/A {"-mode", ".mode", XrmoptionSepArg, (caddr_t) NULL},
546N/A {"-nolock", ".nolock", XrmoptionNoArg, (caddr_t) "on"},
546N/A {"+nolock", ".nolock", XrmoptionNoArg, (caddr_t) "off"},
546N/A {"-remote", ".remote", XrmoptionNoArg, (caddr_t) "on"},
546N/A {"+remote", ".remote", XrmoptionNoArg, (caddr_t) "off"},
546N/A {"-mono", ".mono", XrmoptionNoArg, (caddr_t) "on"},
546N/A {"+mono", ".mono", XrmoptionNoArg, (caddr_t) "off"},
546N/A {"-allowroot", ".allowroot", XrmoptionNoArg, (caddr_t) "on"},
546N/A {"+allowroot", ".allowroot", XrmoptionNoArg, (caddr_t) "off"},
546N/A {"-enablesaver", ".enablesaver", XrmoptionNoArg, (caddr_t) "on"},
546N/A {"+enablesaver", ".enablesaver", XrmoptionNoArg, (caddr_t) "off"},
546N/A {"-allowaccess", ".allowaccess", XrmoptionNoArg, (caddr_t) "on"},
546N/A {"+allowaccess", ".allowaccess", XrmoptionNoArg, (caddr_t) "off"},
546N/A {"-echokeys", ".echokeys", XrmoptionNoArg, (caddr_t) "on"},
546N/A {"+echokeys", ".echokeys", XrmoptionNoArg, (caddr_t) "off"},
546N/A {"-usefirst", ".usefirst", XrmoptionNoArg, (caddr_t) "on"},
546N/A {"+usefirst", ".usefirst", XrmoptionNoArg, (caddr_t) "off"},
546N/A {"-v", ".verbose", XrmoptionNoArg, (caddr_t) "on"},
546N/A {"+v", ".verbose", XrmoptionNoArg, (caddr_t) "off"},
546N/A {"-nice", ".nice", XrmoptionSepArg, (caddr_t) NULL},
546N/A {"-timeout", ".timeout", XrmoptionSepArg, (caddr_t) NULL},
546N/A {"-font", ".font", XrmoptionSepArg, (caddr_t) NULL},
546N/A {"-bg", ".background", XrmoptionSepArg, (caddr_t) NULL},
546N/A {"-fg", ".foreground", XrmoptionSepArg, (caddr_t) NULL},
546N/A {"-background", ".background", XrmoptionSepArg, (caddr_t) NULL},
546N/A {"-foreground", ".foreground", XrmoptionSepArg, (caddr_t) NULL},
546N/A {"-username", ".username", XrmoptionSepArg, (caddr_t) NULL},
546N/A {"-password", ".password", XrmoptionSepArg, (caddr_t) NULL},
546N/A {"-info", ".info", XrmoptionSepArg, (caddr_t) NULL},
546N/A {"-validate", ".validate", XrmoptionSepArg, (caddr_t) NULL},
546N/A {"-invalid", ".invalid", XrmoptionSepArg, (caddr_t) NULL},
546N/A};
546N/A#define genEntries (sizeof genTable / sizeof genTable[0])
546N/A
546N/Astatic XrmOptionDescRec modeTable[] = {
546N/A {"-delay", NULL, XrmoptionSepArg, (caddr_t) NULL},
546N/A {"-batchcount", NULL, XrmoptionSepArg, (caddr_t) NULL},
546N/A {"-saturation", NULL, XrmoptionSepArg, (caddr_t) NULL},
546N/A};
546N/A
546N/A#define MODESPECIFIER0 ".delay"
546N/A#define MODESPECIFIER1 ".batchcount"
546N/A#define MODESPECIFIER2 ".saturation"
546N/A
546N/A#define modeEntries (sizeof modeTable / sizeof modeTable[0])
546N/A
546N/Astatic XrmOptionDescRec cmdlineTable[] = {
546N/A {"-display", ".display", XrmoptionSepArg, (caddr_t) NULL},
546N/A {"-nolock", ".nolock", XrmoptionNoArg, (caddr_t) "on"},
546N/A {"+nolock", ".nolock", XrmoptionNoArg, (caddr_t) "off"},
546N/A {"-remote", ".remote", XrmoptionNoArg, (caddr_t) "on"},
546N/A {"+remote", ".remote", XrmoptionNoArg, (caddr_t) "off"},
546N/A};
546N/A#define cmdlineEntries (sizeof cmdlineTable / sizeof cmdlineTable[0])
546N/A
546N/Astatic XrmOptionDescRec nameTable[] = {
546N/A {"-name", ".name", XrmoptionSepArg, (caddr_t) NULL},
546N/A};
546N/A
546N/A
546N/Atypedef struct {
1233N/A const char *opt;
1233N/A const char *desc;
546N/A} OptionStruct;
546N/A
546N/Astatic OptionStruct opDesc[] = {
546N/A {"-help", "print out this message"},
546N/A {"-resources", "print default resource file to standard output"},
546N/A {"-display displayname", "X server to contact"},
546N/A {"-name resourcename", "class name to use for resources (default is XLock)"},
546N/A {"-/+mono", "turn on/off monochrome override"},
546N/A {"-/+nolock", "turn on/off no password required mode"},
546N/A {"-/+remote", "turn on/off remote host access"},
546N/A {"-/+allowroot", "turn on/off allow root password mode"},
546N/A {"-/+enablesaver", "turn on/off enable X server screen saver"},
546N/A {"-/+allowaccess", "turn on/off allow new clients to connect"},
546N/A {"-/+echokeys", "turn on/off echo '?' for each password key"},
546N/A {"-/+usefirst", "turn on/off using the first char typed in password"},
546N/A {"-/+v", "turn on/off verbose mode"},
546N/A {"-delay usecs", "microsecond delay between screen updates"},
546N/A {"-batchcount num", "number of things per batch"},
546N/A {"-nice level", "nice level for xlock process"},
546N/A {"-timeout seconds", "number of seconds before password times out"},
546N/A {"-saturation value", "saturation of color ramp"},
546N/A {"-font fontname", "font to use for password prompt"},
546N/A {"-bg color", "background color to use for password prompt"},
546N/A {"-fg color", "foreground color to use for password prompt"},
546N/A {"-name string", "text string to use for Name prompt"},
546N/A {"-password string", "text string to use for Password prompt"},
546N/A {"-info string", "text string to use for instructions"},
546N/A {"-validate string", "text string to use for validating password message"},
546N/A {"-invalid string", "text string to use for invalid password message"},
546N/A};
546N/A#define opDescEntries (sizeof opDesc / sizeof opDesc[0])
546N/A
1233N/Aconst char *display;
1233N/Aconst char *mode;
546N/Achar *fontname;
546N/Achar *background;
546N/Achar *foreground;
546N/Achar *text_name;
546N/Achar *text_pass;
546N/Achar *text_info;
546N/Achar *text_valid;
546N/Achar *text_invalid;
546N/Afloat saturation;
546N/Aint nicelevel;
546N/Aint delay;
546N/Aint batchcount;
546N/Aint timeout;
546N/ABool mono;
546N/ABool nolock;
546N/ABool remote;
546N/ABool allowroot;
546N/ABool enablesaver;
546N/ABool allowaccess;
546N/ABool echokeys;
546N/ABool usefirst;
546N/ABool verbose;
546N/A
546N/A#define t_String 0
546N/A#define t_Float 1
546N/A#define t_Int 2
546N/A#define t_Bool 3
546N/A
546N/Atypedef struct {
1233N/A void *var;
1233N/A const char *name;
1233N/A const char *class;
1233N/A const char *def;
546N/A int type;
546N/A} argtype;
546N/A
546N/Astatic argtype genvars[] = {
1233N/A {&fontname, "font", "Font", DEF_FONT, t_String},
1233N/A {&background, "background", "Background", DEF_BG, t_String},
1233N/A {&foreground, "foreground", "Foreground", DEF_FG, t_String},
1233N/A {&text_name, "username", "Username", DEF_NAME, t_String},
1233N/A {&text_pass, "password", "Password", DEF_PASS, t_String},
1233N/A {&text_info, "info", "Info", DEF_INFO, t_String},
1233N/A {&text_valid, "validate", "Validate", DEF_VALID, t_String},
1233N/A {&text_invalid, "invalid", "Invalid", DEF_INVALID, t_String},
1233N/A {&nicelevel, "nice", "Nice", DEF_NICE, t_Int},
1233N/A {&timeout, "timeout", "Timeout", DEF_TIMEOUT, t_Int},
1233N/A {&mono, "mono", "Mono", "off", t_Bool},
1233N/A {&nolock, "nolock", "NoLock", "off", t_Bool},
1233N/A {&remote, "remote", "Remote", "off", t_Bool},
1233N/A {&allowroot, "allowroot", "AllowRoot", "off", t_Bool},
1233N/A {&enablesaver, "enablesaver", "EnableSaver", "off", t_Bool},
1233N/A {&allowaccess, "allowaccess", "AllowAccess", "off", t_Bool},
1233N/A {&echokeys, "echokeys", "EchoKeys", "off", t_Bool},
1233N/A {&usefirst, "usefirst", "Usefirst", "off", t_Bool},
1233N/A {&verbose, "verbose", "Verbose", "off", t_Bool},
546N/A};
546N/A#define NGENARGS (sizeof genvars / sizeof genvars[0])
546N/A
546N/Astatic argtype modevars[] = {
1233N/A {&delay, "delay", "Delay", DEF_DELAY, t_Int},
1233N/A {&batchcount, "batchcount", "BatchCount", DEF_BC, t_Int},
1233N/A {&saturation, "saturation", "Saturation", DEF_SAT, t_Float},
546N/A};
546N/A#define NMODEARGS (sizeof modevars / sizeof modevars[0])
546N/A
546N/A
546N/Astatic void
1233N/ASyntax(const char *badOption)
546N/A{
546N/A int col, len, i;
546N/A
546N/A fprintf(stderr, "%s: bad command line option \"%s\"\n\n",
546N/A ProgramName, badOption);
546N/A
546N/A fprintf(stderr, "usage: %s", ProgramName);
546N/A col = 8 + strlen(ProgramName);
546N/A for (i = 0; i < opDescEntries; i++) {
546N/A len = 3 + strlen(opDesc[i].opt); /* space [ string ] */
546N/A if (col + len > 79) {
546N/A fprintf(stderr, "\n "); /* 3 spaces */
546N/A col = 3;
546N/A }
546N/A fprintf(stderr, " [%s]", opDesc[i].opt);
546N/A col += len;
546N/A }
546N/A
546N/A len = 8 + strlen(LockProcs[0].cmdline_arg);
546N/A if (col + len > 79) {
546N/A fprintf(stderr, "\n "); /* 3 spaces */
546N/A col = 3;
546N/A }
546N/A fprintf(stderr, " [-mode %s", LockProcs[0].cmdline_arg);
546N/A col += len;
546N/A for (i = 1; i < NUMPROCS; i++) {
546N/A len = 3 + strlen(LockProcs[i].cmdline_arg);
546N/A if (col + len > 79) {
546N/A fprintf(stderr, "\n "); /* 3 spaces */
546N/A col = 3;
546N/A }
546N/A fprintf(stderr, " | %s", LockProcs[i].cmdline_arg);
546N/A col += len;
546N/A }
546N/A fprintf(stderr, "]\n");
546N/A
546N/A fprintf(stderr, "\nType %s -help for a full description.\n\n",
546N/A ProgramName);
546N/A exit(1);
546N/A}
546N/A
546N/Astatic void
1233N/AHelp(void)
546N/A{
546N/A int i;
546N/A
546N/A fprintf(stderr, "usage:\n %s [-options ...]\n\n", ProgramName);
546N/A fprintf(stderr, "where options include:\n");
546N/A for (i = 0; i < opDescEntries; i++) {
546N/A fprintf(stderr, " %-28s %s\n", opDesc[i].opt, opDesc[i].desc);
546N/A }
546N/A
546N/A fprintf(stderr, " %-28s %s\n", "-mode mode", "animation mode");
546N/A fprintf(stderr, " where mode is one of:\n");
546N/A for (i = 0; i < NUMPROCS; i++) {
546N/A fprintf(stderr, " %-23s %s\n",
546N/A LockProcs[i].cmdline_arg, LockProcs[i].desc);
546N/A }
546N/A putc('\n', stderr);
546N/A
546N/A exit(0);
546N/A}
546N/A
546N/Astatic void
1233N/ADumpResources(void)
546N/A{
546N/A int i;
546N/A
546N/A printf("%s.mode: %s\n", classname, DEF_MODE);
546N/A
546N/A for (i = 0; i < NGENARGS; i++)
546N/A printf("%s.%s: %s\n",
546N/A classname, genvars[i].name, genvars[i].def);
546N/A
546N/A for (i = 0; i < NUMPROCS - 1; i++) {
546N/A printf("%s.%s.%s: %d\n", classname, LockProcs[i].cmdline_arg,
546N/A "delay", LockProcs[i].def_delay);
546N/A printf("%s.%s.%s: %d\n", classname, LockProcs[i].cmdline_arg,
546N/A "batchcount", LockProcs[i].def_batchcount);
546N/A printf("%s.%s.%s: %g\n", classname, LockProcs[i].cmdline_arg,
546N/A "saturation", LockProcs[i].def_saturation);
546N/A }
546N/A exit(0);
546N/A}
546N/A
546N/A
546N/Astatic void
546N/ALowerString(s)
546N/A char *s;
546N/A{
546N/A
546N/A while (*s) {
546N/A if (isupper(*s))
546N/A *s += ('a' - 'A');
546N/A s++;
546N/A }
546N/A}
546N/A
546N/Astatic void
1233N/AGetResource(
1233N/A XrmDatabase database,
1233N/A const char *parentname,
1233N/A const char *parentclass,
1233N/A const char *name,
1233N/A const char *class,
1233N/A int valueType,
1233N/A const char *def,
1233N/A void *valuep) /* RETURN */
546N/A{
546N/A char *type;
546N/A XrmValue value;
1233N/A const char *string;
546N/A char buffer[BUFSIZ];
546N/A char fullname[BUFSIZ];
546N/A char fullclass[BUFSIZ];
546N/A int len;
546N/A
546N/A/* 4036289. Limit the size of string to print. */
546N/A snprintf(fullname, BUFSIZ, "%s.%s", parentname, name);
546N/A snprintf(fullclass, BUFSIZ, "%s.%s", parentclass, class);
546N/A if (XrmGetResource(database, fullname, fullclass, &type, &value)) {
546N/A string = value.addr;
546N/A len = value.size;
546N/A } else {
546N/A string = def;
546N/A len = strlen(string);
546N/A }
546N/A (void) strncpy(buffer, string, sizeof(buffer));
546N/A buffer[sizeof(buffer) - 1] = '\0';
546N/A
546N/A switch (valueType) {
546N/A case t_String:
546N/A {
546N/A char *s = (char *) malloc(len + 1);
546N/A if (s == (char *) NULL)
1233N/A error("GetResource - couldn't allocate memory");
546N/A (void) strncpy(s, string, len);
546N/A s[len] = '\0';
546N/A *((char **) valuep) = s;
546N/A }
546N/A break;
546N/A case t_Bool:
546N/A LowerString(buffer);
546N/A *((int *) valuep) = (!strcmp(buffer, "true") ||
546N/A !strcmp(buffer, "on") ||
546N/A !strcmp(buffer, "enabled") ||
546N/A !strcmp(buffer, "yes")) ? True : False;
546N/A break;
546N/A case t_Int:
546N/A *((int *) valuep) = atoi(buffer);
546N/A break;
546N/A case t_Float:
546N/A *((float *) valuep) = atof(buffer);
546N/A break;
546N/A }
546N/A}
546N/A
546N/A
546N/Astatic XrmDatabase
546N/Aparsefilepath(xfilesearchpath, TypeName, ClassName)
546N/A char *xfilesearchpath;
546N/A char *TypeName;
546N/A char *ClassName;
546N/A{
546N/A XrmDatabase database = NULL;
546N/A/* 4036289, do not use stack buffer, allocate this buffer from the heap*/
546N/A char *appdefaults;
546N/A char *src;
546N/A char *dst;
546N/A int buflen;
546N/A int bufsize = BUFSIZ;
546N/A
546N/A src = xfilesearchpath;
546N/A
546N/A appdefaults = (char *)malloc(BUFSIZ);
546N/A if (!appdefaults)
546N/A return NULL;
546N/A
546N/A appdefaults[0] = '\0';
546N/A dst = appdefaults;
546N/A while (1) {
546N/A /* Scan through source, expanding % strings as necessary, and
546N/A passing completed paths to XrmGetFileDatabase when ':' or
546N/A end of string is found. To prevent buffer overflows (bug
546N/A 4483090) each time we decide to append to the string, we
546N/A set appenddata to point to the data to be appended &
546N/A appendsize to the size to be appended, and then do all the
546N/A appending & size checking in one place at the end.
546N/A */
546N/A char *appenddata;
546N/A int appendsize = 0;
546N/A
546N/A if (*src == '%') {
546N/A src++;
546N/A switch (*src) {
546N/A case '%':
546N/A case ':':
546N/A appenddata = src++;
546N/A appendsize = 1;
546N/A break;
546N/A case 'T':
546N/A appenddata = TypeName;
546N/A appendsize = strlen(TypeName);
546N/A src++;
546N/A break;
546N/A case 'N':
546N/A appenddata = ClassName;
546N/A appendsize = strlen(ClassName);
546N/A src++;
546N/A break;
546N/A case 'S':
546N/A src++;
546N/A break;
546N/A default:
546N/A src++;
546N/A break;
546N/A }
546N/A } else if (*src == ':') {
546N/A database = XrmGetFileDatabase(appdefaults);
546N/A if (database == NULL) {
546N/A dst = appdefaults;
546N/A *dst = '\0';
546N/A src++;
546N/A } else
546N/A break;
546N/A } else if (*src == '\0') {
546N/A database = XrmGetFileDatabase(appdefaults);
546N/A break;
546N/A } else {
546N/A appenddata = src++;
546N/A appendsize = 1;
546N/A }
546N/A if (appendsize > 0) {
546N/A buflen = dst - appdefaults;
546N/A if (buflen + appendsize >= bufsize) {
546N/A int newsize;
546N/A
546N/A /* Grow by a bit more than we need so we don't have to
546N/A realloc constantly. */
546N/A if (appendsize > BUFSIZ) {
546N/A newsize = bufsize + appendsize;
546N/A } else {
546N/A newsize = bufsize + BUFSIZ;
546N/A }
546N/A
546N/A appdefaults = realloc(appdefaults, newsize);
546N/A if (appdefaults) {
546N/A dst = appdefaults + buflen;
546N/A bufsize = newsize;
546N/A } else {
1233N/A error("parsefilepath - couldn't allocate memory");
546N/A exit(1);
546N/A }
546N/A }
546N/A if (appendsize == 1) {
546N/A *dst++ = *appenddata;
546N/A } else {
546N/A strncat(dst, appenddata, appendsize);
546N/A dst += appendsize;
546N/A }
546N/A *dst = '\0';
546N/A }
546N/A }
546N/A if (appdefaults)
546N/A free(appdefaults);
546N/A return database;
546N/A}
546N/A
546N/A
546N/Astatic void
546N/Aopen_display()
546N/A{
546N/A if (display != NULL) {
546N/A char *colon = strrchr(display, ':');
546N/A int n = colon - display;
546N/A
546N/A if (colon == NULL)
1233N/A error("Malformed -display argument, \"%s\"\n", display);
546N/A
546N/A /*
546N/A * only restrict access to other displays if we are locking and if the
546N/A * Remote resource is not set.
546N/A */
546N/A if (nolock)
546N/A remote = True;
546N/A if (!remote && n
546N/A && strncmp(display, "unix", n)
546N/A && strncmp(display, "localhost", n)) {
546N/A /* 1183055(rfe): xlock doesnt accept long display/host name
546N/A * Get the ip address of $DISPLAY and the machine name.
546N/A * If both are matching then allow to open display.
546N/A * ( also check against the ip addr list returned by gethostbyname.
546N/A * Otherwise, report error and exit.
546N/A * New Local Variables:
546N/A * display_ip contains IP address of the $DISPLAY
546N/A * host_ip contains IP address of the machine_name
546N/A * tmp_display contains the $DISPLAY - [:0.0 or :0]
546N/A * This fix will take care of long host name and IP address form.
546N/A */
546N/A#ifdef IPv6
546N/A struct addrinfo *localhostaddr;
546N/A struct addrinfo *otherhostaddr;
546N/A struct addrinfo *i, *j;
546N/A#else
546N/A struct hostent *host;
546N/A char **hp;
546N/A char display_ip[MAXHOSTNAMELEN];
546N/A char host_ip[MAXHOSTNAMELEN];
546N/A struct hostent *host_display;
546N/A#endif
546N/A int badhost = 1;
546N/A char *tmp_display = malloc(n + 1);
546N/A char hostname[MAXHOSTNAMELEN];
546N/A
546N/A strncpy(tmp_display, display, n);
546N/A tmp_display[n] = '\0';
546N/A
546N/A if (gethostname(hostname, MAXHOSTNAMELEN))
1233N/A error("Can't get local hostname.\n");
546N/A
546N/A#ifdef IPv6
546N/A if (getaddrinfo(hostname, NULL, NULL, &localhostaddr) != 0)
1233N/A error("Can't get address information for %s.\n", hostname);
546N/A
546N/A if (getaddrinfo(tmp_display, NULL, NULL, &otherhostaddr) != 0)
1233N/A error("Can't get address information for %s.\n",
546N/A tmp_display);
546N/A
546N/A for (i = localhostaddr; i != NULL && badhost; i = i->ai_next) {
546N/A for (j = otherhostaddr; j != NULL && badhost; j = j->ai_next) {
546N/A if (i->ai_family == j->ai_family) {
546N/A if (i->ai_family == AF_INET) {
546N/A struct sockaddr_in *sinA
546N/A = (struct sockaddr_in *) i->ai_addr;
546N/A struct sockaddr_in *sinB
546N/A = (struct sockaddr_in *) j->ai_addr;
546N/A struct in_addr *A = &sinA->sin_addr;
546N/A struct in_addr *B = &sinB->sin_addr;
546N/A
546N/A if (memcmp(A,B,sizeof(struct in_addr)) == 0) {
546N/A badhost = 0;
546N/A }
546N/A } else if (i->ai_family == AF_INET6) {
546N/A struct sockaddr_in6 *sinA
546N/A = (struct sockaddr_in6 *) i->ai_addr;
546N/A struct sockaddr_in6 *sinB
546N/A = (struct sockaddr_in6 *) j->ai_addr;
546N/A struct in6_addr *A = &sinA->sin6_addr;
546N/A struct in6_addr *B = &sinB->sin6_addr;
546N/A
546N/A if (memcmp(A,B,sizeof(struct in6_addr)) == 0) {
546N/A badhost = 0;
546N/A }
546N/A }
546N/A }
546N/A }
546N/A }
546N/A
546N/A freeaddrinfo(localhostaddr);
546N/A freeaddrinfo(otherhostaddr);
546N/A
546N/A#else
546N/A if (!(host_display = gethostbyname(tmp_display)))
1233N/A error("Can't get hostbyname %s.\n", tmp_display);
546N/A
546N/A if ( host_display->h_addrtype == AF_INET )
546N/A strcpy(display_ip,inet_ntoa (*host_display->h_addr_list) );
546N/A else
1233N/A error("Unknown address type for %s.\n", tmp_display);
546N/A
546N/A if (!(host = gethostbyname(hostname)))
1233N/A error("Can't get hostbyname.\n");
546N/A
546N/A if ( host->h_addrtype != AF_INET )
1233N/A error("Unknown address type for %s.\n", hostname);
546N/A
546N/A for ( ;*host->h_addr_list; host->h_addr_list++ ) {
546N/A strcpy ( host_ip, inet_ntoa(*host->h_addr_list ) );
546N/A if (!strcmp(display_ip, host_ip ) ) {
546N/A /* check against the list of Internet address */
546N/A badhost = 0;
546N/A break;
546N/A }
546N/A }
546N/A
546N/A if ( badhost ) {
546N/A for (hp = host->h_aliases; *hp; hp++) {
546N/A if (!strncmp(tmp_display, *hp, n)) {
546N/A /* display has been replaced tmp_display because
546N/A * display will be in :0.0 format and tmp_display
546N/A * will have only the hostname/ip_address form.
546N/A */
546N/A badhost = 0;
546N/A break;
546N/A }
546N/A }
546N/A }
546N/A#endif /* IPv6 */
546N/A
546N/A if (badhost) {
546N/A *colon = (char) 0;
1233N/A error("can't lock %s's display\n", display);
546N/A }
546N/A free(tmp_display);
546N/A }
546N/A } else
546N/A display = ":0.0";
546N/A if (!(dsp = XOpenDisplay(display)))
1233N/A error("unable to open display %s.\n", display);
546N/A}
546N/A
546N/A
546N/Avoid
546N/Aprintvar(class, var)
546N/A char *class;
546N/A argtype var;
546N/A{
546N/A switch (var.type) {
546N/A case t_String:
546N/A fprintf(stderr, "%s.%s: %s\n",
546N/A class, var.name, *((char **) var.var));
546N/A break;
546N/A case t_Bool:
546N/A fprintf(stderr, "%s.%s: %s\n",
546N/A class, var.name, *((int *) var.var)
546N/A ? "True" : "False");
546N/A break;
546N/A case t_Int:
546N/A fprintf(stderr, "%s.%s: %d\n",
546N/A class, var.name, *((int *) var.var));
546N/A break;
546N/A case t_Float:
546N/A fprintf(stderr, "%s.%s: %g\n",
546N/A class, var.name, *((float *) var.var));
546N/A break;
546N/A }
546N/A}
546N/A
546N/A
546N/Avoid
1233N/AGetResources(
1233N/A int argc,
1233N/A char *argv[])
546N/A{
546N/A XrmDatabase RDB = NULL;
546N/A XrmDatabase nameDB = NULL;
546N/A XrmDatabase modeDB = NULL;
546N/A XrmDatabase cmdlineDB = NULL;
546N/A XrmDatabase generalDB = NULL;
546N/A XrmDatabase homeDB = NULL;
546N/A XrmDatabase applicationDB = NULL;
546N/A XrmDatabase serverDB = NULL;
546N/A XrmDatabase userDB = NULL;
546N/A char userfile[BUFSIZ];
1233N/A const char *homeenv;
546N/A char *userpath;
546N/A char *env;
546N/A char *serverString;
546N/A int i;
546N/A int modeLength;
546N/A
546N/A XrmInitialize();
546N/A
546N/A /*
546N/A * get -name arg from command line so you can have different resource
546N/A * files for different configurations/machines etc...
546N/A */
546N/A XrmParseCommand(&nameDB, nameTable, 1, ProgramName,
546N/A &argc, argv);
546N/A GetResource(nameDB, ProgramName, "*", "name", "Name", t_String,
546N/A DEF_CLASSNAME, &classname);
546N/A
546N/A
546N/A homeenv = getenv("HOME");
546N/A if (!homeenv)
546N/A homeenv = "";
546N/A
546N/A env = getenv("XFILESEARCHPATH");
546N/A applicationDB = parsefilepath(env ? env : DEF_FILESEARCHPATH,
546N/A "app-defaults", classname);
546N/A
546N/A XrmParseCommand(&cmdlineDB, cmdlineTable, cmdlineEntries, ProgramName,
546N/A &argc, argv);
546N/A
546N/A userpath = getenv("XUSERFILESEARCHPATH");
546N/A if (!userpath) {
546N/A env = getenv("XAPPLRESDIR");
546N/A if (env)
546N/A/* 4036289, Limit the string to print */
546N/A snprintf(userfile, BUFSIZ, "%s/%%N:%s/%%N", env, homeenv);
546N/A else
546N/A/* 4036289, Limit the string to print */
546N/A snprintf(userfile, BUFSIZ, "%s/%%N", homeenv);
546N/A userpath = userfile;
546N/A }
546N/A userDB = parsefilepath(userpath, "app-defaults", classname);
546N/A
546N/A (void) XrmMergeDatabases(applicationDB, &RDB);
546N/A (void) XrmMergeDatabases(userDB, &RDB);
546N/A (void) XrmMergeDatabases(cmdlineDB, &RDB);
546N/A
546N/A env = getenv("DISPLAY");
546N/A GetResource(RDB, ProgramName, classname, "display", "Display", t_String,
546N/A env ? env : DEF_DISPLAY, &display);
546N/A GetResource(RDB, ProgramName, classname, "nolock", "NoLock", t_Bool,
1233N/A "off", &nolock);
546N/A GetResource(RDB, ProgramName, classname, "remote", "Remote", t_Bool,
1233N/A "off", &remote);
546N/A
546N/A open_display();
546N/A serverString = XResourceManagerString(dsp);
546N/A if (serverString) {
546N/A serverDB = XrmGetStringDatabase(serverString);
546N/A (void) XrmMergeDatabases(serverDB, &RDB);
546N/A } else {
546N/A char buf[BUFSIZ];
546N/A/* 4036289, Limit the string to print */
546N/A snprintf(buf, BUFSIZ, "%s/.Xdefaults", homeenv);
546N/A homeDB = XrmGetFileDatabase(buf);
546N/A (void) XrmMergeDatabases(homeDB, &RDB);
546N/A }
546N/A
546N/A XrmParseCommand(&generalDB, genTable, genEntries, ProgramName, &argc, argv);
546N/A (void) XrmMergeDatabases(generalDB, &RDB);
546N/A
546N/A GetResource(RDB, ProgramName, classname, "mode", "Mode", t_String,
1233N/A DEF_MODE, &mode);
546N/A
546N/A /*
546N/A * if random mode, then just grab a random entry from the table
546N/A */
546N/A if (!strncmp(mode, randomstring, strlen(mode)))
546N/A mode = LockProcs[random() % (NUMPROCS - 2)].cmdline_arg;
546N/A
546N/A/* 4036289, Limit the string to print */
546N/A snprintf(modename, BUFSIZ, "%s.%s", ProgramName, mode);
546N/A snprintf(modeclass, BUFSIZ, "%s.%s", classname, mode);
546N/A
546N/A modeLength = strlen(mode);
546N/A modeTable[0].specifier = (char *)malloc(modeLength +
546N/A strlen(MODESPECIFIER0) + 2);
546N/A modeTable[1].specifier = (char *)malloc(modeLength +
546N/A strlen(MODESPECIFIER1) + 2);
546N/A modeTable[2].specifier = (char *)malloc(modeLength +
546N/A strlen(MODESPECIFIER2) + 2);
546N/A
546N/A sprintf(modeTable[0].specifier, "%s.%s", mode, MODESPECIFIER0);
546N/A sprintf(modeTable[1].specifier, "%s.%s", mode, MODESPECIFIER1);
546N/A sprintf(modeTable[2].specifier, "%s.%s", mode, MODESPECIFIER2);
546N/A
546N/A XrmParseCommand(&modeDB, modeTable, modeEntries, ProgramName, &argc, argv);
546N/A (void) XrmMergeDatabases(modeDB, &RDB);
546N/A
546N/A /* Parse the rest of the command line */
546N/A for (argc--, argv++; argc > 0; argc--, argv++) {
546N/A if (**argv != '-')
546N/A Syntax(*argv);
546N/A switch (argv[0][1]) {
546N/A case 'h':
546N/A Help();
546N/A /* NOTREACHED */
546N/A case 'r':
546N/A DumpResources();
546N/A /* NOTREACHED */
546N/A default:
546N/A Syntax(*argv);
546N/A /* NOTREACHED */
546N/A }
546N/A }
546N/A
546N/A /* the RDB is set, now query load the variables from the database */
546N/A
546N/A for (i = 0; i < NGENARGS; i++)
546N/A GetResource(RDB, ProgramName, classname,
546N/A genvars[i].name, genvars[i].class,
546N/A genvars[i].type, genvars[i].def, genvars[i].var);
546N/A
546N/A for (i = 0; i < NMODEARGS; i++)
546N/A GetResource(RDB, modename, modeclass,
546N/A modevars[i].name, modevars[i].class,
546N/A modevars[i].type, modevars[i].def, modevars[i].var);
546N/A
546N/A (void) XrmDestroyDatabase(RDB);
546N/A
546N/A if (verbose) {
546N/A for (i = 0; i < NGENARGS; i++)
546N/A printvar(classname, genvars[i]);
546N/A for (i = 0; i < NMODEARGS; i++)
546N/A printvar(modename, modevars[i]);
546N/A }
546N/A}
546N/A
546N/A
1233N/Avoid
1233N/ACheckResources(void)
546N/A{
546N/A int i;
546N/A
546N/A if (batchcount < 1)
546N/A Syntax("-batchcount argument must be positive.");
546N/A if (saturation < 0.0 || saturation > 1.0)
546N/A Syntax("-saturation argument must be between 0.0 and 1.0.");
546N/A if (delay < 0)
546N/A Syntax("-delay argument must be positive.");
546N/A
546N/A for (i = 0; i < NUMPROCS; i++) {
546N/A if (!strncmp(LockProcs[i].cmdline_arg, mode, strlen(mode))) {
546N/A init = LockProcs[i].lp_init;
546N/A callback = LockProcs[i].lp_callback;
546N/A break;
546N/A }
546N/A }
546N/A if (i == NUMPROCS) {
546N/A fprintf(stderr, "Unknown mode: ");
546N/A Syntax(mode);
546N/A }
546N/A}