~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/rstart/server.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: server.c,v 1.5 2000/08/17 19:54:01 cpqbld Exp $ */
 
2
 
 
3
/************************************************************************/
 
4
/* Copyright (c) 1993 Quarterdeck Office Systems                        */
 
5
/*                                                                      */
 
6
/* Permission to use, copy, modify, distribute, and sell this software  */
 
7
/* and software and its documentation for any purpose is hereby granted */
 
8
/* without fee, provided that the above copyright notice appear in all  */
 
9
/* copies and that both that copyright notice and this permission       */
 
10
/* notice appear in supporting documentation, and that the name         */
 
11
/* Quarterdeck Office Systems, Inc. not be used in advertising or       */
 
12
/* publicity pertaining to distribution of this software without        */
 
13
/* specific, written prior permission.                                  */
 
14
/*                                                                      */
 
15
/* THIS SOFTWARE IS PROVIDED `AS-IS'.  QUARTERDECK OFFICE SYSTEMS,      */
 
16
/* INC., DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,         */
 
17
/* INCLUDING WITHOUT LIMITATION ALL IMPLIED WARRANTIES OF               */
 
18
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR                */
 
19
/* NONINFRINGEMENT.  IN NO EVENT SHALL QUARTERDECK OFFICE SYSTEMS,      */
 
20
/* INC., BE LIABLE FOR ANY DAMAGES WHATSOEVER, INCLUDING SPECIAL,       */
 
21
/* INCIDENTAL OR CONSEQUENTIAL DAMAGES, INCLUDING LOSS OF USE, DATA, OR */
 
22
/* PROFITS, EVEN IF ADVISED OF THE POSSIBILITY THEREOF, AND REGARDLESS  */
 
23
/* OF WHETHER IN AN ACTION IN CONTRACT, TORT OR NEGLIGENCE, ARISING OUT */
 
24
/* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.    */
 
25
/************************************************************************/
 
26
/* $XFree86: xc/programs/rstart/server.c,v 1.5 2001/07/25 15:05:15 dawes Exp $ */
 
27
 
 
28
/* Extended rsh "helper" program */
 
29
#include <stdio.h>
 
30
#include <ctype.h>
 
31
#include <X11/Xos.h>
 
32
#include <errno.h>
 
33
#include <stdlib.h>
 
34
#include <sys/stat.h>
 
35
 
 
36
#ifdef  ODT1_DISPLAY_HACK
 
37
#include <netdb.h>
 
38
#endif  /* ODT1_DISPLAY_HACK */
 
39
 
 
40
#define TRUE    1
 
41
#define FALSE   0
 
42
 
 
43
extern void squish_out_escapes ( char *s );
 
44
extern char * Strdup ( char *s );
 
45
extern int get_a_line ( FILE *f, int *pargc, char ***pargv );
 
46
extern void nomem ( void );
 
47
static char *Strlwr ( char *s0 );
 
48
extern void do_it ( void );
 
49
extern void process ( FILE *f, int is_the_real_thing );
 
50
extern void detach ( void );
 
51
extern void putenv_with_prefix ( char *prefix, char *name, char *value );
 
52
 
 
53
/* auth.c */
 
54
extern void do_auth ( void );
 
55
 
 
56
struct key {
 
57
        char *name;
 
58
        void (*func)(int ac, char **av);
 
59
};
 
60
 
 
61
extern void key_cmd(int ac, char **av);
 
62
extern void key_exec(int ac, char **av);
 
63
extern void key_context(int ac, char **av);
 
64
extern void key_misc(int ac, char **av);
 
65
extern void key_generic_cmd(int ac, char **av);
 
66
extern void key_dir(int ac, char **av);
 
67
extern void key_detach(int ac, char **av);
 
68
extern void key_nodetach(int ac, char **av);
 
69
extern void key_posix_umask(int ac, char **av);
 
70
extern void key_auth(int ac, char **av);
 
71
extern void key_internal_registries(int ac, char **av);
 
72
extern void key_internal_local_default(int ac, char **av);
 
73
extern void key_internal_global_contexts(int ac, char **av);
 
74
extern void key_internal_local_contexts(int ac, char **av);
 
75
extern void key_internal_global_commands(int ac, char **av);
 
76
extern void key_internal_local_commands(int ac, char **av);
 
77
extern void key_internal_variable_prefix(int ac, char **av);
 
78
extern void key_internal_print(int ac, char **av);
 
79
extern void key_internal_auth_program(int ac, char **av);
 
80
extern void key_internal_auth_input(int ac, char **av);
 
81
 
 
82
 
 
83
struct key keys[] = {
 
84
        { "cmd",                        key_cmd },
 
85
        { "exec",                       key_exec },
 
86
        { "context",                    key_context },
 
87
        { "misc",                       key_misc },
 
88
        { "generic-cmd",                key_generic_cmd },
 
89
        { "dir",                        key_dir },
 
90
        { "detach",                     key_detach },
 
91
        { "nodetach",                   key_nodetach },
 
92
        { "posix-umask",                key_posix_umask },
 
93
        { "auth",                       key_auth },
 
94
        { "internal-registries",        key_internal_registries },
 
95
        { "internal-local-default",     key_internal_local_default },
 
96
        { "internal-global-contexts",   key_internal_global_contexts },
 
97
        { "internal-local-contexts",    key_internal_local_contexts },
 
98
        { "internal-global-commands",   key_internal_global_commands },
 
99
        { "internal-local-commands",    key_internal_local_commands },
 
100
        { "internal-variable-prefix",   key_internal_variable_prefix },
 
101
        { "internal-print",             key_internal_print },
 
102
        { "internal-auth-program",      key_internal_auth_program },
 
103
        { "internal-auth-input",        key_internal_auth_input },
 
104
        { NULL,                         NULL }
 
105
};
 
106
 
 
107
 
 
108
char **parm_cmd = NULL;
 
109
char **parm_exec = NULL;
 
110
char **parm_generic_cmd = NULL;
 
111
char *parm_dir = NULL;
 
112
char *parm_context = NULL;
 
113
char **parm_internal_registries = NULL;
 
114
char *parm_internal_local_default = NULL;
 
115
char *parm_internal_global_contexts = NULL;
 
116
char *parm_internal_local_contexts = NULL;
 
117
char *parm_internal_global_commands = NULL;
 
118
char *parm_internal_local_commands = NULL;
 
119
char *parm_internal_variable_prefix = NULL;
 
120
int parm_detach = FALSE;
 
121
 
 
122
char *parm_global_default = DEFAULT_CONFIG;
 
123
char    myname[]=SERVERNAME;
 
124
 
 
125
int
 
126
main(int argc, char *argv[])
 
127
{
 
128
        FILE *f;
 
129
 
 
130
        if(argc == 3 && !strcmp(argv[1], "-c")) parm_global_default = argv[2];
 
131
 
 
132
        setbuf(stdin, NULL);
 
133
 
 
134
        printf(
 
135
            "%s: Ready: version 1.0, May 02 1994 X11R6.3\n",
 
136
            myname);
 
137
        fflush(stdout);
 
138
 
 
139
        f = fopen(parm_global_default, "r");
 
140
        if(f) process(f, FALSE);
 
141
 
 
142
        if(parm_internal_local_default) {
 
143
                /* We start in $HOME */
 
144
                f = fopen(parm_internal_local_default, "r");
 
145
                if(f) process(f, FALSE);
 
146
        }
 
147
 
 
148
        process(stdin, TRUE);
 
149
 
 
150
        do_it();
 
151
        exit(0);
 
152
}
 
153
 
 
154
void
 
155
squish_out_escapes(s)
 
156
char *s;
 
157
{
 
158
        char *p;
 
159
        char *o;
 
160
 
 
161
        o = s;
 
162
        for(p = s; *p; p++) {
 
163
                if(*p == '\\') {
 
164
                        if(p[1] >= '0' && p[1] <= '3'
 
165
                        && p[2] >= '0' && p[2] <= '7'
 
166
                        && p[3] >= '0' && p[3] <= '7') {
 
167
                                *o++ = ((p[1]-'0') << 6)
 
168
                                        + ((p[2]-'0') << 3)
 
169
                                        + (p[3]-'0');
 
170
                                p += 3;
 
171
                        } else {
 
172
                                printf(
 
173
                        "%s: Failure: Improper \\ escape\n",myname);
 
174
                                exit(255);
 
175
                        }
 
176
                } else *o++ = *p;
 
177
        }
 
178
        *o = '\0';
 
179
}
 
180
 
 
181
char *
 
182
Strdup(s)
 
183
    char *s;
 
184
{
 
185
    char *cs;
 
186
 
 
187
    if (!s)
 
188
        return s;
 
189
    cs = malloc(strlen(s)+1);
 
190
    strcpy(cs, s);
 
191
    return cs;
 
192
}
 
193
 
 
194
int
 
195
get_a_line(f, pargc, pargv)
 
196
FILE *f;
 
197
int *pargc;
 
198
char ***pargv;
 
199
{
 
200
        char buf[2048];
 
201
        char *p;
 
202
        int c;
 
203
        char **pa;
 
204
        int was_space;
 
205
        char *saved;
 
206
 
 
207
        while(1) {
 
208
                p = buf;
 
209
                while((c = getc(f)) != '\n') {
 
210
                        switch(c) {
 
211
                            case '\0':
 
212
                            case '\r':
 
213
                                /* Ignored, per spec */
 
214
                                break;
 
215
                            case EOF:
 
216
                                return FALSE;
 
217
                            default:
 
218
                                *p++ = c;
 
219
                                break;
 
220
                        }
 
221
                }
 
222
                *p = '\0';
 
223
 
 
224
                saved = Strdup(buf);
 
225
                if(!saved) nomem();
 
226
 
 
227
                *pargc = 0;
 
228
                was_space = TRUE;
 
229
                for(p = saved; *p; p++) {
 
230
                        if(was_space && !isspace(*p)) (*pargc)++;
 
231
                        was_space = isspace(*p);
 
232
                }
 
233
 
 
234
                *pargv = (char **)malloc((*pargc+1)*sizeof(char *));
 
235
                if(!*pargv) nomem();
 
236
 
 
237
                pa = *pargv;
 
238
                was_space = TRUE;
 
239
                for(p = saved; *p; p++) {
 
240
                        if(was_space && !isspace(*p)) *pa++ = p;
 
241
                        was_space = isspace(*p);
 
242
                        if(isspace(*p)) *p = '\0';
 
243
                }
 
244
                *pa = NULL;
 
245
 
 
246
                if(*pargc > 0 && (*pargv)[0][0] == '#') {
 
247
                        /* How embarrassing.  All that work for a comment. */
 
248
                        free(saved);
 
249
                        free(*pargv);
 
250
                        continue;
 
251
                }
 
252
 
 
253
                break;
 
254
        }
 
255
 
 
256
        for(pa = *pargv; *pa; pa++) {
 
257
                squish_out_escapes(*pa);
 
258
        }
 
259
 
 
260
        return TRUE;
 
261
}
 
262
 
 
263
void
 
264
nomem()
 
265
{
 
266
        printf("%s: Failure: Out of memory\n",myname);
 
267
        exit(255);
 
268
}
 
269
 
 
270
void
 
271
key_internal_registries(ac, av)
 
272
int ac;
 
273
char **av;
 
274
{
 
275
        parm_internal_registries = av+1;
 
276
}
 
277
 
 
278
void
 
279
key_internal_variable_prefix(ac, av)
 
280
int ac;
 
281
char **av;
 
282
{
 
283
        if(ac != 2) {
 
284
                printf(
 
285
                    "%s: Failure: Malformed INTERNAL-VARIABLE-PREFIX\n",myname);
 
286
                exit(255);
 
287
        }
 
288
        parm_internal_variable_prefix = av[1];
 
289
}
 
290
 
 
291
void
 
292
key_internal_local_default(ac, av)
 
293
int ac;
 
294
char **av;
 
295
{
 
296
        if(ac != 2) {
 
297
                printf("%s: Failure: Malformed INTERNAL-LOCAL-DEFAULT\n",myname);
 
298
                exit(255);
 
299
        }
 
300
        parm_internal_local_default = av[1];
 
301
}
 
302
 
 
303
void
 
304
key_internal_global_commands(ac, av)
 
305
int ac;
 
306
char **av;
 
307
{
 
308
        if(ac != 2) {
 
309
                printf("%s: Failure: Malformed INTERNAL-GLOBAL-COMMANDS\n",myname);
 
310
                exit(255);
 
311
        }
 
312
        parm_internal_global_commands = av[1];
 
313
}
 
314
 
 
315
void
 
316
key_internal_local_commands(ac, av)
 
317
int ac;
 
318
char **av;
 
319
{
 
320
        if(ac != 2) {
 
321
                printf("%s: Failure: Malformed INTERNAL-LOCAL-COMMANDS\n",myname);
 
322
                exit(255);
 
323
        }
 
324
        parm_internal_local_commands = av[1];
 
325
}
 
326
 
 
327
void
 
328
key_internal_global_contexts(ac, av)
 
329
int ac;
 
330
char **av;
 
331
{
 
332
        if(ac != 2) {
 
333
                printf("%s: Failure: Malformed INTERNAL-GLOBAL-CONTEXTS\n",myname);
 
334
                exit(255);
 
335
        }
 
336
        parm_internal_global_contexts = av[1];
 
337
}
 
338
 
 
339
void
 
340
key_internal_local_contexts(ac, av)
 
341
int ac;
 
342
char **av;
 
343
{
 
344
        if(ac != 2) {
 
345
                printf("%s: Failure: Malformed INTERNAL-LOCAL-CONTEXTS\n",myname);
 
346
                exit(255);
 
347
        }
 
348
        parm_internal_local_contexts = av[1];
 
349
}
 
350
 
 
351
void
 
352
key_cmd(ac, av)
 
353
int ac;
 
354
char **av;
 
355
{
 
356
        if(parm_cmd || parm_exec || parm_generic_cmd) {
 
357
                printf(
 
358
        "%s: Failure: more than one of CMD, EXEC, GENERIC-CMD\n",myname);
 
359
                exit(255);
 
360
        }
 
361
        parm_cmd = av;
 
362
}
 
363
 
 
364
void
 
365
key_exec(ac, av)
 
366
int ac;
 
367
char **av;
 
368
{
 
369
        if(parm_cmd || parm_exec || parm_generic_cmd) {
 
370
                printf(
 
371
        "%s: Failure: more than one of CMD, EXEC, GENERIC-CMD\n",myname);
 
372
                exit(255);
 
373
        }
 
374
        parm_exec = av;
 
375
}
 
376
 
 
377
static char *
 
378
Strlwr(s0)
 
379
char *s0;
 
380
{
 
381
        char *s;
 
382
 
 
383
        for(s = s0; *s; s++) {
 
384
                if(isupper(*s)) *s = tolower(*s);
 
385
        }
 
386
        return s0;
 
387
}
 
388
 
 
389
 
 
390
void
 
391
key_context(ac, av)
 
392
int ac;
 
393
char **av;
 
394
{
 
395
        char buf[1024];
 
396
        int ok;
 
397
        FILE *f;
 
398
 
 
399
        if(ac != 2) {
 
400
                printf("%s: Failure: Malformed CONTEXT\n",myname);
 
401
                exit(255);
 
402
        }
 
403
        Strlwr(av[1]);
 
404
        parm_context = av[1];
 
405
 
 
406
        ok = FALSE;
 
407
 
 
408
        if(parm_internal_global_contexts) {
 
409
                strcpy(buf, parm_internal_global_contexts);
 
410
                strcat(buf, "/");
 
411
                strcat(buf, parm_context);
 
412
                if((f = fopen(buf, "r"))) {
 
413
                        process(f, FALSE);
 
414
                        ok = TRUE;
 
415
                }
 
416
        }
 
417
 
 
418
        if(parm_internal_local_contexts) {
 
419
                strcpy(buf, parm_internal_local_contexts);
 
420
                strcat(buf, "/");
 
421
                strcat(buf, parm_context);
 
422
                if((f = fopen(buf, "r"))) {
 
423
                        process(f, FALSE);
 
424
                        ok = TRUE;
 
425
                }
 
426
        }
 
427
 
 
428
        if(!ok) {
 
429
                printf("%s: Error: Unknown context '%s'\n",myname, parm_context);
 
430
                exit(255);
 
431
        }
 
432
}
 
433
 
 
434
void
 
435
key_dir(ac, av)
 
436
int ac;
 
437
char **av;
 
438
{
 
439
        if(ac != 2) {
 
440
                printf("%s: Failure: malformed DIR line\n",myname);
 
441
                exit(255);
 
442
        }
 
443
        parm_dir = av[1];
 
444
}
 
445
 
 
446
void
 
447
key_misc(ac, av)
 
448
int ac;
 
449
char **av;
 
450
{
 
451
        char **pp;
 
452
 
 
453
        if(ac != 3) {
 
454
                printf("%s: Failure: malformed MISC line\n",myname);
 
455
                exit(255);
 
456
        }
 
457
 
 
458
        Strlwr(av[1]);
 
459
 
 
460
        if(parm_internal_registries) {
 
461
                for(pp = parm_internal_registries; *pp; pp++) {
 
462
                        if(!strcmp(av[1], *pp)) goto ok;
 
463
                }
 
464
        }
 
465
        printf("%s: Warning: registry %s not recognized\n",myname, av[1]);
 
466
        fflush(stdout);
 
467
 
 
468
ok:
 
469
        ;
 
470
 
 
471
#ifdef  ODT1_DISPLAY_HACK
 
472
        /* The X apps in ODT version 1 don't know how to look up */
 
473
        /* host names using DNS.  Do it for them. */
 
474
        if(!strcmp(av[1], "x")
 
475
        && !strncmp(av[2], "DISPLAY=", 8)
 
476
        && odt1_display_hack(av[2]+8)) return;
 
477
#endif  /* ODT1_DISPLAY_HACK */
 
478
 
 
479
        putenv(av[2]);
 
480
}
 
481
 
 
482
#ifdef  ODT1_DISPLAY_HACK
 
483
odt1_display_hack(s)
 
484
char *s;
 
485
{
 
486
        char buf[80];
 
487
        struct hostent *he;
 
488
        char *p;
 
489
        int ok;
 
490
 
 
491
        ok = FALSE;
 
492
        for(p = s; *p; p++) {
 
493
                if(*p == ':') {
 
494
                        if(!ok) break;
 
495
                        *p = '\0';
 
496
                        he = gethostbyname(s);
 
497
                        *p = ':';
 
498
                        if(!he) break;
 
499
                        sprintf(buf, "DISPLAY=%u.%u.%u.%u%s",
 
500
                                he->h_addr_list[0][0] & 0xff,
 
501
                                he->h_addr_list[0][1] & 0xff,
 
502
                                he->h_addr_list[0][2] & 0xff,
 
503
                                he->h_addr_list[0][3] & 0xff,
 
504
                                p);
 
505
                        s = Strdup(buf);
 
506
                        if(!s) nomem();
 
507
                        putenv(s);
 
508
                        return TRUE;
 
509
                }
 
510
                if(!isdigit(*p) && *p != '.') ok = TRUE;
 
511
        }
 
512
        return FALSE;
 
513
}
 
514
#endif  /* ODT1_DISPLAY_HACK */
 
515
 
 
516
void
 
517
key_generic_cmd(ac, av)
 
518
int ac;
 
519
char **av;
 
520
{
 
521
        if(parm_cmd || parm_exec || parm_generic_cmd) {
 
522
                printf(
 
523
        "%s: Failure: more than one of CMD, EXEC, GENERIC-CMD\n",myname);
 
524
                exit(255);
 
525
        }
 
526
        parm_generic_cmd = av;
 
527
}
 
528
 
 
529
void
 
530
do_it(void)
 
531
{
 
532
        if(parm_dir) {
 
533
                if(chdir(parm_dir)) {
 
534
                        printf("%s: Error: %s - %s\n",myname,
 
535
                                parm_dir, strerror(errno));
 
536
                        exit(255);
 
537
                }
 
538
        }
 
539
 
 
540
        if(parm_internal_variable_prefix) {
 
541
                putenv_with_prefix(parm_internal_variable_prefix,
 
542
                        "CONTEXT", parm_context);
 
543
                putenv_with_prefix(parm_internal_variable_prefix,
 
544
                        "LOCAL_COMMANDS", parm_internal_local_commands);
 
545
                putenv_with_prefix(parm_internal_variable_prefix,
 
546
                        "GLOBAL_COMMANDS", parm_internal_global_commands);
 
547
                putenv_with_prefix(parm_internal_variable_prefix,
 
548
                        "LOCAL_CONTEXTS", parm_internal_local_contexts);
 
549
                putenv_with_prefix(parm_internal_variable_prefix,
 
550
                        "GLOBAL_CONTEXTS", parm_internal_global_contexts);
 
551
        }
 
552
 
 
553
        do_auth();
 
554
 
 
555
        if(parm_cmd) {
 
556
                char *shell;
 
557
                char *buf;
 
558
                int len;
 
559
                char **pa;
 
560
 
 
561
                if(!(shell = getenv("SHELL"))) shell = "/bin/sh";
 
562
 
 
563
                len = 0;
 
564
                for(pa = parm_cmd+1; *pa; pa++) {
 
565
                        len += strlen(*pa) + 1;
 
566
                }
 
567
 
 
568
                buf = malloc(len+1);
 
569
                if(!buf) nomem();
 
570
 
 
571
                buf[0] = '\0';
 
572
                for(pa = parm_cmd+1; *pa; pa++) {
 
573
                        strcat(buf, " ");
 
574
                        strcat(buf, *pa);
 
575
                }
 
576
 
 
577
                printf("%s: Success: about to exec %s -c %s\n",myname,
 
578
                        shell, buf+1);
 
579
                fflush(stdout);
 
580
 
 
581
                if(parm_detach) detach();
 
582
 
 
583
                execl(shell, shell, "-c", buf+1, (char *)NULL);
 
584
                printf("%s: Error: %s - %s\n",myname,
 
585
                        shell, strerror(errno));
 
586
                exit(255);
 
587
        }
 
588
 
 
589
        if(parm_exec) {
 
590
                printf("%s: Success: about to exec %s with args\n",myname,
 
591
                        parm_exec[1]);
 
592
                fflush(stdout);
 
593
 
 
594
                if(parm_detach) detach();
 
595
 
 
596
                execvp(parm_exec[1], parm_exec+2);
 
597
                printf("%s: Error: %s - %s\n",myname,
 
598
                        parm_exec[0], strerror(errno));
 
599
                exit(255);
 
600
        }
 
601
 
 
602
        if(parm_generic_cmd) {
 
603
                char buf[1024];
 
604
 
 
605
                if(!parm_internal_local_commands
 
606
                && !parm_internal_global_commands) {
 
607
                        printf(
 
608
        "%s: Failure: No generic command directory!\n",myname);
 
609
                        exit(255);
 
610
                }
 
611
 
 
612
                printf("%s: Success: about to exec generic command\n",myname);
 
613
                fflush(stdout);
 
614
 
 
615
                if(parm_detach) detach();
 
616
 
 
617
                /* Try context-specific generic commands first */
 
618
                if(parm_context) {
 
619
                        if(parm_internal_local_commands) {
 
620
                                strcpy(buf, parm_internal_local_commands);
 
621
                                strcat(buf, "/");
 
622
                                strcat(buf, parm_context);
 
623
                                strcat(buf, "/");
 
624
                                strcat(buf, parm_generic_cmd[1]);
 
625
                                execv(buf, parm_generic_cmd+1);
 
626
                        }
 
627
 
 
628
                        if(parm_internal_global_commands) {
 
629
                                strcpy(buf, parm_internal_global_commands);
 
630
                                strcat(buf, "/");
 
631
                                strcat(buf, parm_context);
 
632
                                strcat(buf, "/");
 
633
                                strcat(buf, parm_generic_cmd[1]);
 
634
                                execv(buf, parm_generic_cmd+1);
 
635
                        }
 
636
                }
 
637
 
 
638
                /* Failing that, try non-context-specific */
 
639
                if(parm_internal_local_commands) {
 
640
                        strcpy(buf, parm_internal_local_commands);
 
641
                        strcat(buf, "/");
 
642
                        strcat(buf, parm_generic_cmd[1]);
 
643
                        execv(buf, parm_generic_cmd+1);
 
644
                }
 
645
 
 
646
                if(parm_internal_global_commands) {
 
647
                        strcpy(buf, parm_internal_global_commands);
 
648
                        strcat(buf, "/");
 
649
                        strcat(buf, parm_generic_cmd[1]);
 
650
                        execv(buf, parm_generic_cmd+1);
 
651
                }
 
652
 
 
653
                printf("%s: Error: %s - %s\n",myname,
 
654
                        buf, strerror(errno));
 
655
                exit(255);
 
656
        }
 
657
 
 
658
        printf("%s: Failure: No CMD, EXEC, or GENERIC-CMD.\n",myname);
 
659
        exit(255);
 
660
}
 
661
 
 
662
void
 
663
process(f, is_the_real_thing)
 
664
FILE *f;
 
665
int is_the_real_thing;
 
666
{
 
667
        int line_argc;
 
668
        char **line_argv;
 
669
        struct key *pk;
 
670
 
 
671
        while(1) {
 
672
                if(!get_a_line(f, &line_argc, &line_argv)) {
 
673
                        if(is_the_real_thing) {
 
674
                                printf(
 
675
                "%s: Failure: No blank line after request\n",myname);
 
676
                                exit(255);
 
677
                        }
 
678
                        return;
 
679
                }
 
680
 
 
681
                if(line_argc == 0) {
 
682
                        if(is_the_real_thing) return;
 
683
                        continue;
 
684
                }
 
685
 
 
686
                Strlwr(line_argv[0]);
 
687
                for(pk = keys; pk->name; pk++) {
 
688
                        if(!strcmp(line_argv[0], pk->name)) {
 
689
                                (*pk->func)(line_argc, line_argv);
 
690
                                goto ok;
 
691
                        }
 
692
                }
 
693
                printf("%s: Failure: %s not recognized\n",myname, line_argv[0]);
 
694
                exit(255);
 
695
ok:
 
696
                ;
 
697
        }
 
698
}
 
699
 
 
700
void
 
701
key_internal_print(ac, av)
 
702
int ac;
 
703
char **av;
 
704
{
 
705
        printf("%s: Debug:",myname);
 
706
        while(*++av) printf(" %s", *av);
 
707
        printf("\n");
 
708
}
 
709
 
 
710
void
 
711
key_detach(ac,av)
 
712
int ac;
 
713
char **av;
 
714
{
 
715
        parm_detach = TRUE;
 
716
}
 
717
 
 
718
void
 
719
key_nodetach(ac,av)
 
720
int ac;
 
721
char **av;
 
722
{
 
723
        parm_detach = FALSE;
 
724
}
 
725
 
 
726
void
 
727
detach(void)
 
728
{
 
729
        /* I'm not exactly sure how you're supposed to handle stdio here */
 
730
        switch(fork()) {
 
731
            case -1:
 
732
                printf("%s: Error: fork - %s\n",myname, strerror(errno));
 
733
                exit(255);
 
734
            case 0:
 
735
                /* Child */
 
736
                close(0);
 
737
                close(1);
 
738
                close(2);
 
739
                dup(dup(open("/dev/null", O_RDWR)));
 
740
                return;
 
741
            default:
 
742
                /* Parent */
 
743
                _exit(0);
 
744
        }
 
745
}
 
746
 
 
747
void
 
748
putenv_with_prefix(prefix, name, value)
 
749
char *prefix;
 
750
char *name;
 
751
char *value;
 
752
{
 
753
        char *s;
 
754
 
 
755
        if(!value) return;
 
756
 
 
757
        s = malloc(strlen(prefix) + strlen(name) + strlen(value) + 3);
 
758
 
 
759
        if(!s) nomem();
 
760
 
 
761
        sprintf(s, "%s_%s=%s", prefix, name, value);
 
762
 
 
763
        putenv(s);
 
764
}
 
765
 
 
766
void
 
767
key_posix_umask(ac, av)
 
768
int ac;
 
769
char **av;
 
770
{
 
771
        unsigned i;
 
772
        char *s;
 
773
 
 
774
        if(ac != 2) {
 
775
                printf(
 
776
        "%s: Failure: Malformed POSIX-UMASK - wrong number of args\n",myname);
 
777
                exit(255);
 
778
        }
 
779
 
 
780
        i = strtol(av[1], &s, 8);
 
781
 
 
782
        if(*s || i < 0 || i > 0777) {
 
783
                printf(
 
784
        "%s: Failure: Malformed POSIX-UMASK - bad arg\n",myname);
 
785
                exit(255);
 
786
        }
 
787
 
 
788
        umask(i);
 
789
}
 
790
 
 
791
#ifdef NOPUTENV
 
792
/*
 
793
 * define our own putenv() if the system doesn't have one.
 
794
 * putenv(s): place s (a string of the form "NAME=value") in
 
795
 * the environment; replacing any existing NAME.  s is placed in
 
796
 * environment, so if you change s, the environment changes (like
 
797
 * putenv on a sun).  Binding removed if you putenv something else
 
798
 * called NAME.
 
799
 */
 
800
int
 
801
putenv(s)
 
802
    char *s;
 
803
{
 
804
    char *v;
 
805
    int varlen, idx;
 
806
    extern char **environ;
 
807
    char **newenv;
 
808
    static int virgin = 1; /* true while "environ" is a virgin */
 
809
 
 
810
    v = index(s, '=');
 
811
    if(v == 0)
 
812
        return 0; /* punt if it's not of the right form */
 
813
    varlen = (v + 1) - s;
 
814
 
 
815
    for (idx = 0; environ[idx] != 0; idx++) {
 
816
        if (strncmp(environ[idx], s, varlen) == 0) {
 
817
            if(v[1] != 0) { /* true if there's a value */
 
818
                environ[idx] = s;
 
819
                return 0;
 
820
            } else {
 
821
                do {
 
822
                    environ[idx] = environ[idx+1];
 
823
                } while(environ[++idx] != 0);
 
824
                return 0;
 
825
            }
 
826
        }
 
827
    }
 
828
    
 
829
    /* add to environment (unless no value; then just return) */
 
830
    if(v[1] == 0)
 
831
        return 0;
 
832
    if(virgin) {
 
833
        register i;
 
834
 
 
835
        newenv = (char **) malloc((unsigned) ((idx + 2) * sizeof(char*)));
 
836
        if(newenv == 0)
 
837
            return -1;
 
838
        for(i = idx-1; i >= 0; --i)
 
839
            newenv[i] = environ[i];
 
840
        virgin = 0;     /* you're not a virgin anymore, sweety */
 
841
    } else {
 
842
        newenv = (char **) realloc((char *) environ,
 
843
                                   (unsigned) ((idx + 2) * sizeof(char*)));
 
844
        if (newenv == 0)
 
845
            return -1;
 
846
    }
 
847
 
 
848
    environ = newenv;
 
849
    environ[idx] = s;
 
850
    environ[idx+1] = 0;
 
851
    
 
852
    return 0;
 
853
}
 
854
#endif /* NOPUTENV */