Link with C++ linker
[oweals/cde.git] / cde / programs / dtscreen / resource.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: resource.c /main/4 1996/06/19 09:47:56 mustafa $ */
24 /*
25  */
26 /*                                                                      *
27  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
28  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
29  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
30  * (c) Copyright 1993, 1994 Novell, Inc.                                *
31  */
32 /*-
33  * resource.c - resource management for dtscreen, the X Window System lockscreen.
34  *
35  * Copyright (c) 1991 by Patrick J. Naughton.
36  *
37  * See dtscreen.c for copying information.
38  *
39  * Revision History:
40  * 25-Sep-91: added worm mode.
41  * 06-Jun-91: Added flame mode.
42  * 16-May-91: Added random mode and pyro mode.
43  * 26-Mar-91: CheckResources: delay must be >= 0.
44  * 29-Oct-90: Added #include <ctype.h> for missing isupper() on some OS revs.
45  *            moved -mode option, reordered Xrm database evaluation.
46  * 28-Oct-90: Added text strings.
47  * 26-Oct-90: Fix bug in mode specific options.
48  * 31-Jul-90: Fix ':' handling in parsefilepath
49  * 07-Jul-90: Created from resource work in dtscreen.c
50  *
51  */
52
53 #include <stdio.h>
54 #include <stdlib.h>
55 #include "dtscreen.h"
56 #include <netdb.h>
57 #include <math.h>
58 #include <ctype.h>
59
60 #include <X11/Xresource.h>
61
62 /*              include file for message texts          */
63 #include <limits.h>
64 #include <nl_types.h>
65 #define MF_DTSCREEN "dtscreen.cat"
66
67 #include <locale.h>
68 extern nl_catd  scmc_catd;   /* Cat descriptor for scmc conversion */
69
70 /*
71  * Declare external interface routines for supported screen savers.
72  */
73
74 extern void inithop();
75 extern void drawhop();
76
77 extern void initlife();
78 extern void drawlife();
79
80 extern void initqix();
81 extern void drawqix();
82
83 extern void initimage();
84 extern void drawimage();
85
86 extern void initblank();
87 extern void drawblank();
88
89 extern void initswarm();
90 extern void drawswarm();
91
92 extern void initrotor();
93 extern void drawrotor();
94
95 extern void initpyro();
96 extern void drawpyro();
97
98 extern void initflame();
99 extern void drawflame();
100
101 extern void initworm();
102 extern void drawworm();
103
104 typedef struct {
105     char       *cmdline_arg;
106     void        (*lp_init) ();
107     void        (*lp_callback) ();
108     int         def_delay;
109     int         def_batchcount;
110     float       def_saturation;
111     char       *desc;
112 }           LockStruct;
113
114 static char randomstring[] = "random";
115
116 static LockStruct LockProcs[] = {
117     {"hop", inithop, drawhop, 0, 1000, 1.0, "Hopalong iterated fractals"},
118     {"qix", initqix, drawqix, 30000, 64, 1.0, "Spinning lines a la Qix(tm)"},
119     {"image", initimage, drawimage, 2000000, 8, 0.3, "Random bouncing image"},
120     {"life", initlife, drawlife, 1000000, 100, 1.0, "Conway's game of Life"},
121     {"swarm", initswarm, drawswarm, 10000, 100, 1.0, "Swarm of bees"},
122     {"rotor", initrotor, drawrotor, 10000, 4, 0.4, "Rotor"},
123     {"pyro", initpyro, drawpyro, 15000, 40, 1.0, "Fireworks"},
124     {"flame", initflame, drawflame, 10000, 20, 1.0, "Cosmic Flame Fractals"},
125     {"worm", initworm, drawworm, 10000, 20, 1.0, "Wiggly Worms"},
126     {"blank", initblank, drawblank, 5000000, 1, 1.0, "Blank screen"},
127     {randomstring, NULL, NULL, 0, 0, 0.0, "Random mode"},
128 };
129 #define NUMPROCS (sizeof LockProcs / sizeof LockProcs[0])
130
131
132 extern char *getenv();
133
134 #ifndef DEF_FILESEARCHPATH
135 #define DEF_FILESEARCHPATH "/usr/lib/X11/%T/%N%S"
136 #endif
137 #define DEF_DISPLAY     ":0"
138 #define DEF_MODE        "swarm"
139 #define DEF_BG          "White"
140 #define DEF_FG          "Black"
141 #define DEF_BC          "100"   /* vectors (or whatever) per batch */
142 #define DEF_DELAY       "200000"/* microseconds between batches */
143 #define DEF_NICE        "10"    /* dtscreen process nicelevel */
144 #define DEF_SAT         "1.0"   /* color ramp saturation 0->1 */
145 #define DEF_CLASSNAME   "Dtscreen"
146
147 static char *classname;
148 static char modename[1024];
149 static char modeclass[1024];
150
151 static XrmOptionDescRec genTable[] = {
152     {"-mode", ".mode", XrmoptionSepArg, (caddr_t) NULL},
153     {"-mono", ".mono", XrmoptionNoArg, (caddr_t) "on"},
154     {"+mono", ".mono", XrmoptionNoArg, (caddr_t) "off"},
155     {"-nice", ".nice", XrmoptionSepArg, (caddr_t) NULL},
156     {"-create",  ".create", XrmoptionNoArg, (caddr_t) "on"},
157 };
158 #define genEntries (sizeof genTable / sizeof genTable[0])
159
160 /*************************************************************/
161 /** This table was changed for AIX.  In order to read these **/
162 /** command line options properly, the specifier field must **/
163 /** be built on the fly.                                    **/
164 /*************************************************************/
165 static XrmOptionDescRec modeTable[] = {
166     {"-delay",      NULL, XrmoptionSepArg, (caddr_t) NULL},
167     {"-batchcount", NULL, XrmoptionSepArg, (caddr_t) NULL},
168     {"-saturation", NULL, XrmoptionSepArg, (caddr_t) NULL},
169 };
170 #define modeEntries (sizeof modeTable / sizeof modeTable[0])
171
172 static XrmOptionDescRec cmdlineTable[] = {
173     {"-display", ".display", XrmoptionSepArg, (caddr_t) NULL},
174     {"-xrm",     NULL,       XrmoptionResArg, (caddr_t) NULL},
175 };
176 #define cmdlineEntries (sizeof cmdlineTable / sizeof cmdlineTable[0])
177
178 static XrmOptionDescRec nameTable[] = {
179     {"-name", ".name", XrmoptionSepArg, (caddr_t) NULL},
180 };
181
182
183 typedef struct {
184     char       *opt;
185     char       *desc;
186 }           OptionStruct;
187
188 static OptionStruct opDesc[] = {
189     {"-help", "print out this message"},
190     {"-resources", "print default resource file to standard output"},
191     {"-display displayname", "X server to contact"},
192     {"-/+mono", "turn on/off monochrome override"},
193     {"-delay usecs", "microsecond delay between screen updates"},
194     {"-batchcount num", "number of things per batch"},
195     {"-nice level", "nice level for dtscreen process"},
196     {"-saturation value", "saturation of color ramp"},
197     {"-create", "create a window in which to draw"},
198 };
199 #define opDescEntries (sizeof opDesc / sizeof opDesc[0])
200
201 char       *display;
202 char       *mode;
203 float       saturation;
204 int         nicelevel;
205 int         delay;
206 int         batchcount;
207 Bool        mono;
208 Bool        create;
209
210
211 #define t_String        0
212 #define t_Float         1
213 #define t_Int           2
214 #define t_Bool          3
215
216 typedef struct {
217     caddr_t    *var;
218     char       *name;
219     char       *class;
220     char       *def;
221     int         type;
222 }           argtype;
223
224 static argtype genvars[] = {
225     {(caddr_t *) &nicelevel, "nice", "Nice", DEF_NICE, t_Int},
226     {(caddr_t *) &mono, "mono", "Mono", "off", t_Bool},
227     {(caddr_t *) &create, "create", "Create", "off", t_Bool},
228 };
229 #define NGENARGS (sizeof genvars / sizeof genvars[0])
230
231 static argtype modevars[] = {
232     {(caddr_t *) &delay, "delay", "Delay", DEF_DELAY, t_Int},
233     {(caddr_t *) &batchcount, "batchcount", "BatchCount", DEF_BC, t_Int},
234     {(caddr_t *) &saturation, "saturation", "Saturation", DEF_SAT, t_Float},
235 };
236 #define NMODEARGS (sizeof modevars / sizeof modevars[0])
237
238
239 static void
240 Syntax(badOption)
241     char       *badOption;
242 {
243     int         col, len, i;
244
245 #ifdef MIT_R5
246     fprintf(stderr, "%s:  bad command line option:  %s.\n\n",
247             ProgramName, badOption);
248 #else
249     fprintf(stderr, catgets(scmc_catd, 2, 1,
250         "%s:  Bad command line option:  %s.\n\n"), 
251         ProgramName, badOption);
252 #endif
253
254     fprintf(stderr, "usage:  %s", ProgramName);
255     col = 8 + strlen(ProgramName);
256     for (i = 0; i < opDescEntries; i++) {
257         len = 3 + strlen(opDesc[i].opt);        /* space [ string ] */
258         if (col + len > 79) {
259             fprintf(stderr, "\n   ");   /* 3 spaces */
260             col = 3;
261         }
262         fprintf(stderr, " [%s]", opDesc[i].opt);
263         col += len;
264     }
265
266     len = 8 + strlen(LockProcs[0].cmdline_arg);
267     if (col + len > 79) {
268         fprintf(stderr, "\n   ");       /* 3 spaces */
269         col = 3;
270     }
271     fprintf(stderr, " [-mode %s", LockProcs[0].cmdline_arg);
272     col += len;
273     for (i = 1; i < NUMPROCS; i++) {
274         len = 3 + strlen(LockProcs[i].cmdline_arg);
275         if (col + len > 79) {
276             fprintf(stderr, "\n   ");   /* 3 spaces */
277             col = 3;
278         }
279         fprintf(stderr, " | %s", LockProcs[i].cmdline_arg);
280         col += len;
281     }
282     fprintf(stderr, "]\n");
283
284 #ifdef MIT_R5
285     fprintf(stderr, "\nType %s -help for a full description.\n\n",
286             ProgramName);
287 #else
288     fprintf(stderr, catgets(scmc_catd, 2, 2,
289         "\nType %s -help for a full description.\n\n"), 
290         ProgramName);
291 #endif
292     exit(1);
293 }
294
295 static void
296 Help()
297 {
298     int         i;
299
300 #ifdef MIT_R5
301     fprintf(stderr, "usage:\n        %s [-options ...]\n\n", ProgramName);
302     fprintf(stderr, "where options include:\n");
303
304 #else
305     fprintf(stderr, catgets(scmc_catd, 2, 3,
306         "Usage:\n        %s [-options ...]\n\n\
307         where options include:\n"), ProgramName);
308 #endif
309
310     for (i = 0; i < opDescEntries; i++) {
311         fprintf(stderr, "    %-28s %s\n", opDesc[i].opt, opDesc[i].desc);
312     }
313
314 #ifdef MIT_R5
315     fprintf(stderr, "    %-28s %s\n", "-mode mode", "animation mode");
316     fprintf(stderr, "    where mode is one of:\n");
317 #else
318     fprintf(stderr, catgets(scmc_catd, 2, 5, 
319          "    %-28s %s\n\t where mode is one of:\n"), 
320          "-mode mode", "animation mode");
321 #endif
322     for (i = 0; i < NUMPROCS; i++) {
323         fprintf(stderr, "          %-23s %s\n",
324                 LockProcs[i].cmdline_arg, LockProcs[i].desc);
325     }
326     putc('\n', stderr);
327
328     exit(0);
329 }
330
331 static void
332 DumpResources()
333 {
334     int         i;
335
336     printf("%s.mode: %s\n", classname, DEF_MODE);
337
338     for (i = 0; i < NGENARGS; i++)
339         printf("%s.%s: %s\n",
340                classname, genvars[i].name, genvars[i].def);
341
342     for (i = 0; i < NUMPROCS - 1; i++) {
343         printf("%s.%s.%s: %d\n", classname, LockProcs[i].cmdline_arg,
344                "delay", LockProcs[i].def_delay);
345         printf("%s.%s.%s: %d\n", classname, LockProcs[i].cmdline_arg,
346                "batchcount", LockProcs[i].def_batchcount);
347         printf("%s.%s.%s: %g\n", classname, LockProcs[i].cmdline_arg,
348                "saturation", LockProcs[i].def_saturation);
349     }
350     exit(0);
351 }
352
353
354 static void
355 LowerString(s)
356     char       *s;
357 {
358
359     while (*s) {
360         if (isupper(*s))
361             *s += ('a' - 'A');
362         s++;
363     }
364 }
365
366 static void
367 GetResource(database, parentname, parentclass,
368             name, class, valueType, def, valuep)
369     XrmDatabase database;
370     char       *parentname;
371     char       *parentclass;
372     char       *name;
373     char       *class;
374     int         valueType;
375     char       *def;
376     caddr_t    *valuep;         /* RETURN */
377 {
378     char       *type;
379     XrmValue    value;
380     char       *string;
381     char        buffer[1024];
382     char        fullname[1024];
383     char        fullclass[1024];
384     int         len;
385
386     sprintf(fullname, "%s.%s", parentname, name);
387     sprintf(fullclass, "%s.%s", parentclass, class);
388     if (XrmGetResource(database, fullname, fullclass, &type, &value)) {
389         string = value.addr;
390         len = value.size;
391     } else {
392         string = def;
393         len = strlen(string);
394     }
395     (void) strncpy(buffer, string, sizeof(buffer));
396     buffer[sizeof(buffer) - 1] = '\0';
397
398     switch (valueType) {
399     case t_String:
400         {
401             char       *s;
402             s = (char *) malloc(len + 1);
403             if (s == (char *) NULL)
404 #ifdef MIT_R5
405                 error("%s: GetResource - couldn't allocate memory");
406 #else
407             {
408                 fprintf(stderr, catgets(scmc_catd, 2, 18, 
409                      "%s: GetResource - couldn't allocate memory.\n"),ProgramName);
410                 exit(1);
411             }
412 #endif
413             (void) strncpy(s, string, len);
414             s[len] = '\0';
415             *((char **) valuep) = s;
416         }
417         break;
418     case t_Bool:
419         LowerString(buffer);
420         *((int *) valuep) = (!strcmp(buffer, "true") ||
421                              !strcmp(buffer, "on") ||
422                              !strcmp(buffer, "enabled") ||
423                              !strcmp(buffer, "yes")) ? True : False;
424         break;
425     case t_Int:
426         *((int *) valuep) = atoi(buffer);
427         break;
428     case t_Float:
429         *((float *) valuep) = (float) atof(buffer);
430         break;
431     }
432 }
433
434
435 static      XrmDatabase
436 parsefilepath(xfilesearchpath, TypeName, ClassName)
437     char       *xfilesearchpath;
438     char       *TypeName;
439     char       *ClassName;
440 {
441     XrmDatabase database = NULL;
442     char        appdefaults[1024];
443     char       *src;
444     char       *dst;
445
446     src = xfilesearchpath;
447     appdefaults[0] = '\0';
448     dst = appdefaults;
449     while (1) {
450         if (*src == '%') {
451             src++;
452             switch (*src) {
453             case '%':
454             case ':':
455                 *dst++ = *src++;
456                 *dst = '\0';
457                 break;
458             case 'T':
459                 (void) strcat(dst, TypeName);
460                 src++;
461                 dst += strlen(TypeName);
462                 break;
463             case 'N':
464                 (void) strcat(dst, ClassName);
465                 src++;
466                 dst += strlen(ClassName);
467                 break;
468             case 'S':
469                 src++;
470                 break;
471             default:
472                 src++;
473                 break;
474             }
475         } else if (*src == ':') {
476             database = XrmGetFileDatabase(appdefaults);
477             if (database == NULL) {
478                 dst = appdefaults;
479                 src++;
480             } else
481                 break;
482         } else if (*src == '\0') {
483             database = XrmGetFileDatabase(appdefaults);
484             break;
485         } else {
486             *dst++ = *src++;
487             *dst = '\0';
488         }
489     }
490     return database;
491 }
492
493 /*******************************************************************/
494 /** screenIOErrorHandler                                          **/
495 /**                                                               **/
496 /** this function will exit cleanly when the connection is broken **/
497 /*******************************************************************/
498 static int screenIOErrorHandler(dpy)
499         Display *dpy;
500 {
501         exit(1);
502         return 1;
503 }
504
505 static void
506 open_display()
507 {
508     if (display != NULL) {
509         char       *colon = strchr(display, ':');
510         int         n = colon - display;
511
512         if (colon == NULL)
513 #ifdef MIT_R5
514             error("%s: Malformed -display argument, \"%s\"\n", display);
515 #else
516         {
517             fprintf(stderr, catgets(scmc_catd, 2, 19,
518                 "%s: Malformed -display argument:  %s.\n"), ProgramName,display);
519             exit(1);
520         }
521 #endif
522
523     } else
524         display = ":0.0";
525     if (!(dsp = XOpenDisplay(display)))
526 #ifdef MIT_R5
527         error("%s: unable to open display %s.\n", display);
528 #else
529     {
530         fprintf(stderr, catgets(scmc_catd, 2, 17,
531                 "%s: Unable to open display %s.\n"),ProgramName, display);
532         exit(1);
533     }
534 #endif
535
536     XSetIOErrorHandler(screenIOErrorHandler);
537 }
538
539 void
540 printvar(class, var)
541     char       *class;
542     argtype     var;
543 {
544     switch (var.type) {
545     case t_String:
546         fprintf(stderr, "%s.%s: %s\n",
547                 class, var.name, *((char **) var.var));
548         break;
549     case t_Bool:
550         fprintf(stderr, "%s.%s: %s\n",
551                 class, var.name, *((int *) var.var)
552                 ? "True" : "False");
553         break;
554     case t_Int:
555         fprintf(stderr, "%s.%s: %d\n",
556                 class, var.name, *((int *) var.var));
557         break;
558     case t_Float:
559         fprintf(stderr, "%s.%s: %g\n",
560                 class, var.name, *((float *) var.var));
561         break;
562     }
563 }
564
565
566 void
567 GetResources(argc, argv)
568     int         argc;
569     char       *argv[];
570 {
571     XrmDatabase RDB = NULL;
572     XrmDatabase modeDB = NULL;
573     XrmDatabase nameDB = NULL;
574     XrmDatabase cmdlineDB = NULL;
575     XrmDatabase generalDB = NULL;
576     XrmDatabase homeDB = NULL;
577     XrmDatabase applicationDB = NULL;
578     XrmDatabase serverDB = NULL;
579     XrmDatabase userDB = NULL;
580     char        userfile[1024];
581     char       *homeenv;
582     char       *userpath;
583     char       *env;
584     char       *serverString;
585     int         i;
586     /***************************/
587     /** new variables for AIX **/
588     /***************************/
589     char        delaySpecifier[64];
590     char        batchcountSpecifier[64];
591     char        saturationSpecifier[64];
592
593     XrmInitialize();
594
595     for (i = 0; i < argc; i++) {
596         if (!strncmp(argv[i], "-help", strlen(argv[i])))
597             Help();
598         /* NOTREACHED */
599     }
600
601     /*
602      * get -name arg from command line so you can have different resource
603      * files for different configurations/machines etc...
604      */
605     XrmParseCommand(&nameDB, nameTable, 1, ProgramName,
606                     &argc, argv);
607     GetResource(nameDB, ProgramName, "*", "name", "Name", t_String,
608                 DEF_CLASSNAME, &classname);
609
610     homeenv = getenv("HOME");
611     if (!homeenv)
612         homeenv = "";
613
614     env = getenv("XFILESEARCHPATH");
615     applicationDB = parsefilepath(env ? env : DEF_FILESEARCHPATH,
616                                   "app-defaults", classname);
617
618     XrmParseCommand(&cmdlineDB, cmdlineTable, cmdlineEntries, ProgramName,
619                     &argc, argv);
620
621     userpath = getenv("XUSERFILESEARCHPATH");
622     if (!userpath) {
623         env = getenv("XAPPLRESDIR");
624         if (env)
625             sprintf(userfile, "%s/%%N:%s/%%N", env, homeenv);
626         else
627             sprintf(userfile, "%s/%%N", homeenv);
628         userpath = userfile;
629     }
630     userDB = parsefilepath(userpath, "app-defaults", classname);
631
632     (void) XrmMergeDatabases(applicationDB, &RDB);
633     (void) XrmMergeDatabases(userDB, &RDB);
634     (void) XrmMergeDatabases(cmdlineDB, &RDB);
635
636     env = getenv("DISPLAY");
637     GetResource(RDB, ProgramName, classname, "display", "Display", t_String,
638                 env ? env : DEF_DISPLAY, &display);
639     open_display();
640     serverString = XResourceManagerString(dsp);
641     if (serverString) {
642         serverDB = XrmGetStringDatabase(serverString);
643         (void) XrmMergeDatabases(serverDB, &RDB);
644     } else {
645         char        buf[1024];
646         sprintf(buf, "%s/.Xdefaults", homeenv);
647         homeDB = XrmGetFileDatabase(buf);
648         (void) XrmMergeDatabases(homeDB, &RDB);
649     }
650
651     XrmParseCommand(&generalDB, genTable, genEntries, ProgramName, &argc, argv);
652     (void) XrmMergeDatabases(generalDB, &RDB);
653
654     GetResource(RDB, ProgramName, classname, "mode", "Mode", t_String,
655                 DEF_MODE, (caddr_t *) &mode);
656
657     /*
658      * if random< mode, then just grab a random entry from the table
659      */
660     if (!strcmp(mode, randomstring))
661         mode = LockProcs[random() % (NUMPROCS - 2)].cmdline_arg;
662
663     sprintf(modename, "%s.%s", ProgramName, mode);
664     sprintf(modeclass, "%s.%s", classname, mode);
665
666
667     /*********************************************************************/
668     /** New code for AIX                                                **/
669     /** We must build the specifier fields of the modeTable on the fly. **/
670     /*********************************************************************/
671     sprintf(delaySpecifier,      ".%s.delay",      mode);
672     sprintf(batchcountSpecifier, ".%s.batchcount", mode);
673     sprintf(saturationSpecifier, ".%s.saturation", mode);
674     modeTable[0].specifier = delaySpecifier;
675     modeTable[1].specifier = batchcountSpecifier;
676     modeTable[2].specifier = saturationSpecifier;
677
678
679     XrmParseCommand(&modeDB, modeTable, modeEntries, ProgramName, &argc, argv);
680     (void) XrmMergeDatabases(modeDB, &RDB);
681
682     /* Parse the rest of the command line */
683     for (argc--, argv++; argc > 0; argc--, argv++) {
684         if (**argv != '-')
685             Syntax(*argv);
686         switch (argv[0][1]) {
687         case 'r':
688             DumpResources();
689             /* NOTREACHED */
690         default:
691             Syntax(*argv);
692             /* NOTREACHED */
693         }
694     }
695
696     /* the RDB is set, now query load the variables from the database */
697
698     for (i = 0; i < NGENARGS; i++)
699         GetResource(RDB, ProgramName, classname,
700                     genvars[i].name, genvars[i].class,
701                     genvars[i].type, genvars[i].def, genvars[i].var);
702
703     for (i = 0; i < NMODEARGS; i++)
704         GetResource(RDB, modename, modeclass,
705                     modevars[i].name, modevars[i].class,
706                     modevars[i].type, modevars[i].def, modevars[i].var);
707
708     (void) XrmDestroyDatabase(RDB);
709
710 }
711
712
713 CheckResources()
714 {
715     int         i;
716
717     if (batchcount < 1)
718         Syntax("-batchcount argument must be positive.");
719     if (saturation < 0.0 || saturation > 1.0)
720         Syntax("-saturation argument must be between 0.0 and 1.0.");
721     if (delay < 0)
722         Syntax("-delay argument must be positive.");
723
724     for (i = 0; i < NUMPROCS; i++) {
725         if (!strncmp(LockProcs[i].cmdline_arg, mode, strlen(mode))) {
726             init = LockProcs[i].lp_init;
727             callback = LockProcs[i].lp_callback;
728             break;
729         }
730     }
731     if (i == NUMPROCS) {
732 #ifdef MIT_R5
733         fprintf(stderr, "Unknown mode: ");
734 #else
735         fprintf(stderr, catgets(scmc_catd, 2, 7, 
736              "Unknown mode: "));
737 #endif
738         Syntax(mode);
739     }
740 }