~ubuntu-branches/ubuntu/maverick/kdebase-workspace/maverick-proposed

« back to all changes in this revision

Viewing changes to .pc/07_kdmrc_defaults_kubuntu.diff/kdm/kfrontend/genkdmconf.c

  • Committer: Bazaar Package Importer
  • Author(s): Alessandro Ghersi
  • Date: 2010-07-08 01:11:52 UTC
  • mfrom: (1.1.43 upstream)
  • Revision ID: james.westby@ubuntu.com-20100708011152-z0h26httnjr91mmy
Tags: 4:4.4.92-0ubuntu1
* New upstream rc release:
  - Bump kde-sc-dev-latest to 4.4.92
  - Refresh patches
  - Update symbols
  - plasma-widgets-workspace replaces/conflicts plasma-widget-logout

Show diffs side-by-side

added added

removed removed

Lines of Context:
55
55
#define RCVERSTR stringify(RCVERMAJOR) "." stringify(RCVERMINOR)
56
56
 
57
57
static int old_scripts, no_old_scripts, old_confs, no_old,
58
 
        no_backup, no_in_notice, use_destdir, mixed_scripts;
 
58
    no_backup, no_in_notice, use_destdir, mixed_scripts;
59
59
static const char *newdir = KDMCONF, *facesrc = KDMDATA "/pics/users",
60
 
        *oldxdm, *oldkde, *oldkdepfx;
 
60
    *oldxdm, *oldkde, *oldkdepfx;
61
61
 
62
62
static int oldver;
63
63
 
64
64
 
65
65
typedef struct StrList {
66
 
        struct StrList *next;
67
 
        const char *str;
 
66
    struct StrList *next;
 
67
    const char *str;
68
68
} StrList;
69
69
 
70
70
typedef struct StrMap {
71
 
        struct StrMap *next;
72
 
        const char *key, *value;
 
71
    struct StrMap *next;
 
72
    const char *key, *value;
73
73
} StrMap;
74
74
 
75
75
 
76
76
static void *
77
 
mmalloc( size_t sz )
78
 
{
79
 
        void *ptr;
80
 
 
81
 
        if (!(ptr = malloc( sz ))) {
82
 
                fprintf( stderr, "Out of memory\n" );
83
 
                exit( 1 );
84
 
        }
85
 
        return ptr;
86
 
}
87
 
 
88
 
static void *
89
 
mcalloc( size_t sz )
90
 
{
91
 
        void *ptr;
92
 
 
93
 
        if (!(ptr = calloc( 1, sz ))) {
94
 
                fprintf( stderr, "Out of memory\n" );
95
 
                exit( 1 );
96
 
        }
97
 
        return ptr;
98
 
}
99
 
 
100
 
static void *
101
 
mrealloc( void *optr, size_t sz )
102
 
{
103
 
        void *ptr;
104
 
 
105
 
        if (!(ptr = realloc( optr, sz ))) {
106
 
                fprintf( stderr, "Out of memory\n" );
107
 
                exit( 1 );
108
 
        }
109
 
        return ptr;
 
77
mmalloc(size_t sz)
 
78
{
 
79
    void *ptr;
 
80
 
 
81
    if (!(ptr = malloc(sz))) {
 
82
        fprintf(stderr, "Out of memory\n");
 
83
        exit(1);
 
84
    }
 
85
    return ptr;
 
86
}
 
87
 
 
88
static void *
 
89
mcalloc(size_t sz)
 
90
{
 
91
    void *ptr;
 
92
 
 
93
    if (!(ptr = calloc(1, sz))) {
 
94
        fprintf(stderr, "Out of memory\n");
 
95
        exit(1);
 
96
    }
 
97
    return ptr;
 
98
}
 
99
 
 
100
static void *
 
101
mrealloc(void *optr, size_t sz)
 
102
{
 
103
    void *ptr;
 
104
 
 
105
    if (!(ptr = realloc(optr, sz))) {
 
106
        fprintf(stderr, "Out of memory\n");
 
107
        exit(1);
 
108
    }
 
109
    return ptr;
110
110
}
111
111
 
112
112
static char *
113
 
mstrdup( const char *optr )
 
113
mstrdup(const char *optr)
114
114
{
115
 
        char *ptr;
 
115
    char *ptr;
116
116
 
117
 
        if (!optr)
118
 
                return 0;
119
 
        if (!(ptr = strdup( optr ))) {
120
 
                fprintf( stderr, "Out of memory\n" );
121
 
                exit( 1 );
122
 
        }
123
 
        return ptr;
 
117
    if (!optr)
 
118
        return 0;
 
119
    if (!(ptr = strdup(optr))) {
 
120
        fprintf(stderr, "Out of memory\n");
 
121
        exit(1);
 
122
    }
 
123
    return ptr;
124
124
}
125
125
 
126
126
 
129
129
#include <printf.c>
130
130
 
131
131
typedef struct {
132
 
        char *buf;
133
 
        int clen, blen, tlen;
 
132
    char *buf;
 
133
    int clen, blen, tlen;
134
134
} OCABuf;
135
135
 
136
136
static void
137
 
outCh_OCA( void *bp, char c )
138
 
{
139
 
        OCABuf *ocabp = (OCABuf *)bp;
140
 
 
141
 
        ocabp->tlen++;
142
 
        if (ocabp->clen >= ocabp->blen) {
143
 
                ocabp->blen = ocabp->blen * 3 / 2 + 100;
144
 
                ocabp->buf = mrealloc( ocabp->buf, ocabp->blen );
145
 
        }
146
 
        ocabp->buf[ocabp->clen++] = c;
147
 
}
148
 
 
149
 
static int
150
 
VASPrintf( char **strp, const char *fmt, va_list args )
151
 
{
152
 
        OCABuf ocab = { 0, 0, 0, -1 };
153
 
 
154
 
        doPrint( outCh_OCA, &ocab, fmt, args );
155
 
        outCh_OCA( &ocab, 0 );
156
 
        *strp = realloc( ocab.buf, ocab.clen );
157
 
        if (!*strp)
158
 
                *strp = ocab.buf;
159
 
        return ocab.tlen;
160
 
}
161
 
 
162
 
static int
163
 
ASPrintf( char **strp, const char *fmt, ... )
164
 
{
165
 
        va_list args;
166
 
        int len;
167
 
 
168
 
        va_start( args, fmt );
169
 
        len = VASPrintf( strp, fmt, args );
170
 
        va_end( args );
171
 
        return len;
 
137
outCh_OCA(void *bp, char c)
 
138
{
 
139
    OCABuf *ocabp = (OCABuf *)bp;
 
140
 
 
141
    ocabp->tlen++;
 
142
    if (ocabp->clen >= ocabp->blen) {
 
143
        ocabp->blen = ocabp->blen * 3 / 2 + 100;
 
144
        ocabp->buf = mrealloc(ocabp->buf, ocabp->blen);
 
145
    }
 
146
    ocabp->buf[ocabp->clen++] = c;
 
147
}
 
148
 
 
149
static int
 
150
VASPrintf(char **strp, const char *fmt, va_list args)
 
151
{
 
152
    OCABuf ocab = { 0, 0, 0, -1 };
 
153
 
 
154
    doPrint(outCh_OCA, &ocab, fmt, args);
 
155
    outCh_OCA(&ocab, 0);
 
156
    *strp = realloc(ocab.buf, ocab.clen);
 
157
    if (!*strp)
 
158
        *strp = ocab.buf;
 
159
    return ocab.tlen;
 
160
}
 
161
 
 
162
static int
 
163
ASPrintf(char **strp, const char *fmt, ...)
 
164
{
 
165
    va_list args;
 
166
    int len;
 
167
 
 
168
    va_start(args, fmt);
 
169
    len = VASPrintf(strp, fmt, args);
 
170
    va_end(args);
 
171
    return len;
172
172
}
173
173
 
174
174
static void
175
 
strCat( char **strp, const char *fmt, ... )
 
175
strCat(char **strp, const char *fmt, ...)
176
176
{
177
 
        char *str, *tstr;
178
 
        va_list args;
179
 
        int el;
 
177
    char *str, *tstr;
 
178
    va_list args;
 
179
    int el;
180
180
 
181
 
        va_start( args, fmt );
182
 
        el = VASPrintf( &str, fmt, args );
183
 
        va_end( args );
184
 
        if (*strp) {
185
 
                int ol = strlen( *strp );
186
 
                tstr = mmalloc( el + ol + 1 );
187
 
                memcpy( tstr, *strp, ol );
188
 
                memcpy( tstr + ol, str, el + 1 );
189
 
                free( *strp );
190
 
                free( str );
191
 
                *strp = tstr;
192
 
        } else
193
 
                *strp = str;
 
181
    va_start(args, fmt);
 
182
    el = VASPrintf(&str, fmt, args);
 
183
    va_end(args);
 
184
    if (*strp) {
 
185
        int ol = strlen(*strp);
 
186
        tstr = mmalloc(el + ol + 1);
 
187
        memcpy(tstr, *strp, ol);
 
188
        memcpy(tstr + ol, str, el + 1);
 
189
        free(*strp);
 
190
        free(str);
 
191
        *strp = tstr;
 
192
    } else {
 
193
        *strp = str;
 
194
    }
194
195
}
195
196
 
196
197
 
197
198
#define WANT_CLOSE 1
198
199
 
199
200
typedef struct File {
200
 
        char *buf, *eof, *cur;
 
201
    char *buf, *eof, *cur;
201
202
#if defined(HAVE_MMAP) && defined(WANT_CLOSE)
202
 
        int ismapped;
 
203
    int ismapped;
203
204
#endif
204
205
} File;
205
206
 
206
207
static int
207
 
readFile( File *file, const char *fn )
 
208
readFile(File *file, const char *fn)
208
209
{
209
 
        off_t flen;
210
 
        int fd;
211
 
 
212
 
        if ((fd = open( fn, O_RDONLY )) < 0)
213
 
                return False;
214
 
 
215
 
        flen = lseek( fd, 0, SEEK_END );
 
210
    off_t flen;
 
211
    int fd;
 
212
 
 
213
    if ((fd = open(fn, O_RDONLY)) < 0)
 
214
        return False;
 
215
 
 
216
    flen = lseek(fd, 0, SEEK_END);
216
217
#ifdef HAVE_MMAP
217
218
# ifdef WANT_CLOSE
218
 
        file->ismapped = False;
 
219
    file->ismapped = False;
219
220
# endif
220
 
        file->buf = mmap( 0, flen + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0 );
 
221
    file->buf = mmap(0, flen + 1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
221
222
# ifdef WANT_CLOSE
222
 
        if (file->buf)
223
 
                file->ismapped = True;
224
 
        else
 
223
    if (file->buf)
 
224
        file->ismapped = True;
 
225
    else
225
226
# else
226
 
        if (!file->buf)
 
227
    if (!file->buf)
227
228
# endif
228
229
#endif
229
 
        {
230
 
                file->buf = mmalloc( flen + 1 );
231
 
                lseek( fd, 0, SEEK_SET );
232
 
                if (read( fd, file->buf, flen ) != flen) {
233
 
                        free( file->buf );
234
 
                        close( fd );
235
 
                        fprintf( stderr, "Cannot read file\n" );
236
 
                        return False; /* maybe better abort? */
237
 
                }
238
 
        }
239
 
        file->eof = file->buf + flen;
240
 
        close( fd );
241
 
        return True;
 
230
    {
 
231
        file->buf = mmalloc(flen + 1);
 
232
        lseek(fd, 0, SEEK_SET);
 
233
        if (read(fd, file->buf, flen) != flen) {
 
234
            free(file->buf);
 
235
            close(fd);
 
236
            fprintf(stderr, "Cannot read file\n");
 
237
            return False; /* maybe better abort? */
 
238
        }
 
239
    }
 
240
    file->eof = file->buf + flen;
 
241
    close(fd);
 
242
    return True;
242
243
}
243
244
 
244
245
#ifdef WANT_CLOSE
245
246
static void
246
 
freeBuf( File *file )
 
247
freeBuf(File *file)
247
248
{
248
249
# ifdef HAVE_MMAP
249
 
        if (file->ismapped)
250
 
                munmap( file->buf, file->eof - file->buf );
251
 
        else
 
250
    if (file->ismapped)
 
251
        munmap(file->buf, file->eof - file->buf);
 
252
    else
252
253
# endif
253
 
                free( file->buf );
 
254
        free(file->buf);
254
255
}
255
256
#endif
256
257
 
257
258
static int
258
 
isTrue( const char *val )
259
 
{
260
 
        return !strcmp( val, "true" ) ||
261
 
               !strcmp( val, "yes" ) ||
262
 
               !strcmp( val, "on" ) ||
263
 
               atoi( val );
264
 
}
265
 
 
266
 
 
267
 
static int
268
 
mkpdirs( const char *name, const char *what )
269
 
{
270
 
        char *mfname = mstrdup( name );
271
 
        int i;
272
 
        struct stat st;
273
 
 
274
 
        for (i = 1; mfname[i]; i++)
275
 
                if (mfname[i] == '/') {
276
 
                        mfname[i] = 0;
277
 
                        if (stat( mfname, &st )) {
278
 
                                if (mkdir( mfname, 0755 )) {
279
 
                                        fprintf( stderr, "Cannot create parent %s of %s directory %s: %s\n",
280
 
                                                 mfname, what, name, strerror( errno ) );
281
 
                                        free( mfname );
282
 
                                        return False;
283
 
                                }
284
 
                                chmod( mfname, 0755 );
285
 
                        }
286
 
                        mfname[i] = '/';
287
 
                }
288
 
        free( mfname );
289
 
        return True;
290
 
}
291
 
 
292
 
static int
293
 
mkdirp( const char *name, int mode, const char *what, int existok )
294
 
{
295
 
        struct stat st;
296
 
 
297
 
        if (stat( name, &st )) {
298
 
                mkpdirs( name, what );
299
 
                if (mkdir( name, mode )) {
300
 
                        fprintf( stderr, "Cannot create %s directory %s: %s\n",
301
 
                                 what, name, strerror( errno ) );
302
 
                        return False;
303
 
                }
304
 
                chmod( name, mode );
305
 
                return True;
306
 
        }
307
 
        return existok;
 
259
isTrue(const char *val)
 
260
{
 
261
    return !strcmp(val, "true") ||
 
262
           !strcmp(val, "yes") ||
 
263
           !strcmp(val, "on") ||
 
264
           atoi(val);
 
265
}
 
266
 
 
267
 
 
268
static int
 
269
mkpdirs(const char *name, const char *what)
 
270
{
 
271
    char *mfname = mstrdup(name);
 
272
    int i;
 
273
    struct stat st;
 
274
 
 
275
    for (i = 1; mfname[i]; i++)
 
276
        if (mfname[i] == '/') {
 
277
            mfname[i] = 0;
 
278
            if (stat(mfname, &st)) {
 
279
                if (mkdir(mfname, 0755)) {
 
280
                    fprintf(stderr, "Cannot create parent %s of %s directory %s: %s\n",
 
281
                            mfname, what, name, strerror(errno));
 
282
                    free(mfname);
 
283
                    return False;
 
284
                }
 
285
                chmod(mfname, 0755);
 
286
            }
 
287
            mfname[i] = '/';
 
288
        }
 
289
    free(mfname);
 
290
    return True;
 
291
}
 
292
 
 
293
static int
 
294
mkdirp(const char *name, int mode, const char *what, int existok)
 
295
{
 
296
    struct stat st;
 
297
 
 
298
    if (stat(name, &st)) {
 
299
        mkpdirs(name, what);
 
300
        if (mkdir(name, mode)) {
 
301
            fprintf(stderr, "Cannot create %s directory %s: %s\n",
 
302
                    what, name, strerror(errno));
 
303
            return False;
 
304
        }
 
305
        chmod(name, mode);
 
306
        return True;
 
307
    }
 
308
    return existok;
308
309
}
309
310
 
310
311
 
311
312
static void
312
 
displace( const char *fn )
 
313
displace(const char *fn)
313
314
{
314
 
        if (!no_backup) {
315
 
                char bn[PATH_MAX + 4];
316
 
                sprintf( bn, "%s.bak", fn ); /* won't overflow if only existing paths are passed */
317
 
                rename( fn, bn );
318
 
        } else
319
 
                unlink( fn );
 
315
    if (!no_backup) {
 
316
        char bn[PATH_MAX + 4];
 
317
        sprintf(bn, "%s.bak", fn); /* won't overflow if only existing paths are passed */
 
318
        rename(fn, bn);
 
319
    } else {
 
320
        unlink(fn);
 
321
    }
320
322
}
321
323
 
322
324
 
324
326
 
325
327
/* Create a new file in KDMCONF */
326
328
static FILE *
327
 
createFile( const char *fn, int mode )
 
329
createFile(const char *fn, int mode)
328
330
{
329
 
        FILE *f;
 
331
    FILE *f;
330
332
 
331
 
        free( curName );
332
 
        ASPrintf( &curName, "%s/%s", newdir, fn );
333
 
        displace( curName );
334
 
        if (!(f = fopen( curName, "w" ))) {
335
 
                fprintf( stderr, "Cannot create %s\n", curName );
336
 
                exit( 1 );
337
 
        }
338
 
        chmod( curName, mode );
339
 
        return f;
 
333
    free(curName);
 
334
    ASPrintf(&curName, "%s/%s", newdir, fn);
 
335
    displace(curName);
 
336
    if (!(f = fopen(curName, "w"))) {
 
337
        fprintf(stderr, "Cannot create %s\n", curName);
 
338
        exit(1);
 
339
    }
 
340
    chmod(curName, mode);
 
341
    return f;
340
342
}
341
343
 
342
344
static void
343
345
writeError()
344
346
{
345
 
        fprintf( stderr, "Warning: cannot write %s (disk full?)\n", curName );
346
 
        unlink( curName );
347
 
        exit( 1 );
 
347
    fprintf(stderr, "Warning: cannot write %s (disk full?)\n", curName);
 
348
    unlink(curName);
 
349
    exit(1);
348
350
}
349
351
 
350
352
static void
351
 
fputs_( const char *str, FILE *f )
 
353
fputs_(const char *str, FILE *f)
352
354
{
353
 
        if (fputs( str, f ) == EOF)
354
 
                writeError();
 
355
    if (fputs(str, f) == EOF)
 
356
        writeError();
355
357
}
356
358
 
357
359
static void
358
360
ATTR_PRINTFLIKE(2, 3)
359
 
fprintf_( FILE *f, const char *fmt, ... )
 
361
fprintf_(FILE *f, const char *fmt, ...)
360
362
{
361
 
        va_list args;
 
363
    va_list args;
362
364
 
363
 
        va_start( args, fmt );
364
 
        if (vfprintf( f, fmt, args ) < 0)
365
 
                writeError();
366
 
        va_end( args );
 
365
    va_start(args, fmt);
 
366
    if (vfprintf(f, fmt, args) < 0)
 
367
        writeError();
 
368
    va_end(args);
367
369
}
368
370
 
369
371
static void
370
 
fclose_( FILE *f )
 
372
fclose_(FILE *f)
371
373
{
372
 
        if (fclose( f ) == EOF)
373
 
                writeError();
 
374
    if (fclose(f) == EOF)
 
375
        writeError();
374
376
}
375
377
 
376
378
 
377
379
static char *
378
 
locate( const char *exe )
 
380
locate(const char *exe)
379
381
{
380
 
        int len;
381
 
        char *path, *pathe, *name, *thenam, nambuf[PATH_MAX+1];
 
382
    int len;
 
383
    char *path, *pathe, *name, *thenam, nambuf[PATH_MAX+1];
382
384
 
383
 
        if (!(path = getenv( "PATH" )))
384
 
                return 0;
385
 
        len = strlen( exe );
386
 
        name = nambuf + PATH_MAX - len;
387
 
        memcpy( name, exe, len + 1 );
388
 
        *--name = '/';
389
 
        do {
390
 
                if (!(pathe = strchr( path, ':' )))
391
 
                        pathe = path + strlen( path );
392
 
                len = pathe - path;
393
 
                if (len && !(len == 1 && *path == '.')) {
394
 
                        thenam = name - len;
395
 
                        if (thenam >= nambuf) {
396
 
                                memcpy( thenam, path, len );
397
 
                                if (!access( thenam, X_OK ))
398
 
                                        return mstrdup( thenam );
399
 
                        }
400
 
                }
401
 
                path = pathe;
402
 
        } while (*path++ != '\0');
403
 
        return 0;
 
385
    if (!(path = getenv("PATH")))
 
386
        return 0;
 
387
    len = strlen(exe);
 
388
    name = nambuf + PATH_MAX - len;
 
389
    memcpy(name, exe, len + 1);
 
390
    *--name = '/';
 
391
    do {
 
392
        if (!(pathe = strchr(path, ':')))
 
393
            pathe = path + strlen(path);
 
394
        len = pathe - path;
 
395
        if (len && !(len == 1 && *path == '.')) {
 
396
            thenam = name - len;
 
397
            if (thenam >= nambuf) {
 
398
                memcpy(thenam, path, len);
 
399
                if (!access(thenam, X_OK))
 
400
                    return mstrdup(thenam);
 
401
            }
 
402
        }
 
403
        path = pathe;
 
404
    } while (*path++ != '\0');
 
405
    return 0;
404
406
}
405
407
 
406
408
static int
407
 
runAndWait( char **args )
 
409
runAndWait(char **args)
408
410
{
409
 
        int pid, ret;
 
411
    int pid, ret;
410
412
 
411
 
        switch ((pid = fork())) {
412
 
        case 0:
413
 
                execv( args[0], args );
414
 
                fprintf( stderr, "Cannot execute %s: %s\n",
415
 
                         args[0], strerror( errno ) );
416
 
                _exit( 127 );
417
 
        case -1:
418
 
                fprintf( stderr, "Cannot fork to execute %s: %s\n",
419
 
                         args[0], strerror( errno ) );
420
 
                return -1;
421
 
        }
422
 
        while (waitpid( pid, &ret, 0 ) < 0)
423
 
                if (errno != EINTR)
424
 
                        return -1;
425
 
        return ret;
 
413
    switch ((pid = fork())) {
 
414
    case 0:
 
415
        execv(args[0], args);
 
416
        fprintf(stderr, "Cannot execute %s: %s\n",
 
417
                args[0], strerror(errno));
 
418
        _exit(127);
 
419
    case -1:
 
420
        fprintf(stderr, "Cannot fork to execute %s: %s\n",
 
421
                args[0], strerror(errno));
 
422
        return -1;
 
423
    }
 
424
    while (waitpid(pid, &ret, 0) < 0)
 
425
        if (errno != EINTR)
 
426
            return -1;
 
427
    return ret;
426
428
}
427
429
 
428
430
 
431
433
 */
432
434
 
433
435
typedef struct Entry {
434
 
        struct Entry *next;
435
 
        struct Ent *spec;
436
 
        const char *value;
437
 
        int active:1;
438
 
        int written:1;
 
436
    struct Entry *next;
 
437
    struct Ent *spec;
 
438
    const char *value;
 
439
    int active:1;
 
440
    int written:1;
439
441
} Entry;
440
442
 
441
443
typedef struct Section {
442
 
        struct Section *next;
443
 
        struct Sect *spec;
444
 
        const char *name;
445
 
        const char *comment;
446
 
        Entry *ents;
 
444
    struct Section *next;
 
445
    struct Sect *spec;
 
446
    const char *name;
 
447
    const char *comment;
 
448
    Entry *ents;
447
449
} Section;
448
450
 
449
451
static Section *config; /* the kdmrc data to be written */
453
455
 */
454
456
 
455
457
typedef struct Ent {
456
 
        const char *key;
457
 
        int prio;
458
 
        void (*func)( Entry *ce, Section *cs );
459
 
        const char *comment;
 
458
    const char *key;
 
459
    int prio;
 
460
    void (*func)(Entry *ce, Section *cs);
 
461
    const char *comment;
460
462
} Ent;
461
463
 
462
464
typedef struct Sect {
463
 
        const char *name;
464
 
        Ent *ents;
465
 
        int nents;
 
465
    const char *name;
 
466
    Ent *ents;
 
467
    int nents;
466
468
} Sect;
467
469
 
468
 
static Sect *findSect( const char *name );
469
 
static Ent *findEnt( Sect *sect, const char *key );
 
470
static Sect *findSect(const char *name);
 
471
static Ent *findEnt(Sect *sect, const char *key);
470
472
 
471
473
/*
472
474
 * Functions to manipulate the current kdmrc data
473
475
 */
474
476
 
475
477
static const char *
476
 
getFqVal( const char *sect, const char *key, const char *defval )
 
478
getFqVal(const char *sect, const char *key, const char *defval)
477
479
{
478
 
        Section *cs;
479
 
        Entry *ce;
 
480
    Section *cs;
 
481
    Entry *ce;
480
482
 
481
 
        for (cs = config; cs; cs = cs->next)
482
 
                if (!strcmp( cs->name, sect )) {
483
 
                        for (ce = cs->ents; ce; ce = ce->next)
484
 
                                if (!strcmp( ce->spec->key, key )) {
485
 
                                        if (ce->active && ce->written)
486
 
                                                return ce->value;
487
 
                                        break;
488
 
                                }
489
 
                        break;
490
 
                }
491
 
        return defval;
 
483
    for (cs = config; cs; cs = cs->next)
 
484
        if (!strcmp(cs->name, sect)) {
 
485
            for (ce = cs->ents; ce; ce = ce->next)
 
486
                if (!strcmp(ce->spec->key, key)) {
 
487
                    if (ce->active && ce->written)
 
488
                        return ce->value;
 
489
                    break;
 
490
                }
 
491
            break;
 
492
        }
 
493
    return defval;
492
494
}
493
495
 
494
496
static void
495
 
putFqVal( const char *sect, const char *key, const char *value )
 
497
putFqVal(const char *sect, const char *key, const char *value)
496
498
{
497
 
        Section *cs, **csp;
498
 
        Entry *ce, **cep;
499
 
 
500
 
        if (!value)
501
 
                return;
502
 
 
503
 
        for (csp = &config; (cs = *csp); csp = &(cs->next))
504
 
                if (!strcmp( sect, cs->name ))
505
 
                        goto havesec;
506
 
        cs = mcalloc( sizeof(*cs) );
507
 
        ASPrintf( (char **)&cs->name, "%s", sect );
508
 
        cs->spec = findSect( sect );
509
 
        *csp = cs;
 
499
    Section *cs, **csp;
 
500
    Entry *ce, **cep;
 
501
 
 
502
    if (!value)
 
503
        return;
 
504
 
 
505
    for (csp = &config; (cs = *csp); csp = &(cs->next))
 
506
        if (!strcmp(sect, cs->name))
 
507
            goto havesec;
 
508
    cs = mcalloc(sizeof(*cs));
 
509
    ASPrintf((char **)&cs->name, "%s", sect);
 
510
    cs->spec = findSect(sect);
 
511
    *csp = cs;
510
512
  havesec:
511
513
 
512
 
        for (cep = &(cs->ents); (ce = *cep); cep = &(ce->next))
513
 
                if (!strcmp( key, ce->spec->key ))
514
 
                        goto haveent;
515
 
        ce = mcalloc( sizeof(*ce) );
516
 
        ce->spec = findEnt( cs->spec, key );
517
 
        *cep = ce;
 
514
    for (cep = &(cs->ents); (ce = *cep); cep = &(ce->next))
 
515
        if (!strcmp(key, ce->spec->key))
 
516
            goto haveent;
 
517
    ce = mcalloc(sizeof(*ce));
 
518
    ce->spec = findEnt(cs->spec, key);
 
519
    *cep = ce;
518
520
  haveent:
519
 
        ASPrintf( (char **)&ce->value, "%s", value );
520
 
        ce->written = ce->active = True;
 
521
    ASPrintf((char **)&ce->value, "%s", value);
 
522
    ce->written = ce->active = True;
521
523
}
522
524
 
523
525
static const char *csect;
525
527
#define setSect(se) csect = se
526
528
 
527
529
static void
528
 
putVal( const char *key, const char *value )
 
530
putVal(const char *key, const char *value)
529
531
{
530
 
        putFqVal( csect, key, value );
 
532
    putFqVal(csect, key, value);
531
533
}
532
534
 
533
535
 
534
536
static void
535
 
writeKdmrc( FILE *f )
 
537
writeKdmrc(FILE *f)
536
538
{
537
 
        Section *cs;
538
 
        Entry *ce;
539
 
        StrList *sl = 0, *sp;
540
 
        const char *cmt;
 
539
    Section *cs;
 
540
    Entry *ce;
 
541
    StrList *sl = 0, *sp;
 
542
    const char *cmt;
541
543
 
542
 
        putFqVal( "General", "ConfigVersion", RCVERSTR );
543
 
        for (cs = config; cs; cs = cs->next) {
544
 
                fprintf_( f, "%s[%s]\n",
545
 
                          cs->comment ? cs->comment : "\n", cs->name );
546
 
                for (ce = cs->ents; ce; ce = ce->next) {
547
 
                        if (ce->spec->comment) {
548
 
                                cmt = ce->spec->comment;
549
 
                                for (sp = sl; sp; sp = sp->next)
550
 
                                        if (sp->str == cmt) {
551
 
                                                cmt = "# See above\n";
552
 
                                                goto havit;
553
 
                                        }
554
 
                                if (!(sp = malloc( sizeof(*sp) )))
555
 
                                        fprintf( stderr, "Warning: Out of memory\n" );
556
 
                                else {
557
 
                                        sp->str = cmt;
558
 
                                        sp->next = sl; sl = sp;
559
 
                                }
560
 
                        } else
561
 
                                cmt = "";
562
 
                  havit:
563
 
                        fprintf_( f, "%s%s%s=%s\n",
564
 
                                  cmt, ce->active ? "" : "#", ce->spec->key, ce->value );
565
 
                }
566
 
        }
 
544
    putFqVal("General", "ConfigVersion", RCVERSTR);
 
545
    for (cs = config; cs; cs = cs->next) {
 
546
        fprintf_(f, "%s[%s]\n",
 
547
                 cs->comment ? cs->comment : "\n", cs->name);
 
548
        for (ce = cs->ents; ce; ce = ce->next) {
 
549
            if (ce->spec->comment) {
 
550
                cmt = ce->spec->comment;
 
551
                for (sp = sl; sp; sp = sp->next)
 
552
                    if (sp->str == cmt) {
 
553
                        cmt = "# See above\n";
 
554
                        goto havit;
 
555
                    }
 
556
                if (!(sp = malloc(sizeof(*sp)))) {
 
557
                    fprintf(stderr, "Warning: Out of memory\n");
 
558
                } else {
 
559
                    sp->str = cmt;
 
560
                    sp->next = sl;
 
561
                    sl = sp;
 
562
                }
 
563
            } else {
 
564
                cmt = "";
 
565
            }
 
566
          havit:
 
567
            fprintf_(f, "%s%s%s=%s\n",
 
568
                     cmt, ce->active ? "" : "#", ce->spec->key, ce->value);
 
569
        }
 
570
    }
567
571
}
568
572
 
569
573
 
779
783
 
780
784
/* Create a copy of a file under KDMCONF and fill it */
781
785
static void
782
 
writeCopy( const char *fn, int mode, time_t stamp, const char *buf, size_t len )
 
786
writeCopy(const char *fn, int mode, time_t stamp, const char *buf, size_t len)
783
787
{
784
 
        char *nname;
785
 
        int fd;
786
 
        struct utimbuf utim;
 
788
    char *nname;
 
789
    int fd;
 
790
    struct utimbuf utim;
787
791
 
788
 
        ASPrintf( &nname, "%s/%s", newdir, fn );
789
 
        displace( nname );
790
 
        mkpdirs( nname, "target" );
791
 
        if ((fd = creat( nname, mode )) < 0) {
792
 
                fprintf( stderr, "Cannot create %s\n", nname );
793
 
                exit( 1 );
794
 
        }
795
 
        if (write( fd, buf, len ) != (ssize_t)len || close( fd ) < 0) {
796
 
                fprintf( stderr, "Cannot write %s (disk full?)\n", nname );
797
 
                unlink( nname );
798
 
                exit( 1 );
799
 
        }
800
 
        if (stamp) {
801
 
                utim.actime = utim.modtime = stamp;
802
 
                utime( nname, &utim );
803
 
        }
804
 
        free( nname );
 
792
    ASPrintf(&nname, "%s/%s", newdir, fn);
 
793
    displace(nname);
 
794
    mkpdirs(nname, "target");
 
795
    if ((fd = creat(nname, mode)) < 0) {
 
796
        fprintf(stderr, "Cannot create %s\n", nname);
 
797
        exit(1);
 
798
    }
 
799
    if (write(fd, buf, len) != (ssize_t)len || close(fd) < 0) {
 
800
        fprintf(stderr, "Cannot write %s (disk full?)\n", nname);
 
801
        unlink(nname);
 
802
        exit(1);
 
803
    }
 
804
    if (stamp) {
 
805
        utim.actime = utim.modtime = stamp;
 
806
        utime(nname, &utim);
 
807
    }
 
808
    free(nname);
805
809
}
806
810
 
807
811
 
808
812
/* returns static array! */
809
813
static const char *
810
 
reSect( const char *sec, const char *name )
 
814
reSect(const char *sec, const char *name)
811
815
{
812
 
        static char sname[64];
813
 
        char *p;
 
816
    static char sname[64];
 
817
    char *p;
814
818
 
815
 
        if ((p = strrchr( sec, '-' ))) {
816
 
                sprintf( sname, "%.*s-%s", (int)(p - sec), sec, name );
817
 
                return sname;
818
 
        } else
819
 
                return name;
 
819
    if ((p = strrchr(sec, '-'))) {
 
820
        sprintf(sname, "%.*s-%s", (int)(p - sec), sec, name);
 
821
        return sname;
 
822
    } else {
 
823
        return name;
 
824
    }
820
825
}
821
826
 
822
827
static int
823
 
inNewDir( const char *name )
 
828
inNewDir(const char *name)
824
829
{
825
 
        return !memcmp( name, KDMCONF "/", sizeof(KDMCONF) );
 
830
    return !memcmp(name, KDMCONF "/", sizeof(KDMCONF));
826
831
}
827
832
 
828
833
static const char *
829
 
getMapping( StrMap *sm, const char *k )
 
834
getMapping(StrMap *sm, const char *k)
830
835
{
831
 
        for (; sm; sm = sm->next)
832
 
                if (!strcmp( sm->key, k ))
833
 
                        return sm->value;
834
 
        return 0;
 
836
    for (; sm; sm = sm->next)
 
837
        if (!strcmp(sm->key, k))
 
838
            return sm->value;
 
839
    return 0;
835
840
}
836
841
 
837
842
static void
838
 
addMapping( StrMap **sm, const char *k, const char *v )
 
843
addMapping(StrMap **sm, const char *k, const char *v)
839
844
{
840
 
        for (; *sm; sm = &(*sm)->next)
841
 
                if (!strcmp( (*sm)->key, k ))
842
 
                        return;
843
 
        *sm = mcalloc( sizeof(**sm) );
844
 
        ASPrintf( (char **)&(*sm)->key, "%s", k );
845
 
        ASPrintf( (char **)&(*sm)->value, "%s", v );
 
845
    for (; *sm; sm = &(*sm)->next)
 
846
        if (!strcmp((*sm)->key, k))
 
847
            return;
 
848
    *sm = mcalloc(sizeof(**sm));
 
849
    ASPrintf((char **)&(*sm)->key, "%s", k);
 
850
    ASPrintf((char **)&(*sm)->value, "%s", v);
846
851
}
847
852
 
848
853
static int
849
 
inList( StrList *sp, const char *s )
 
854
inList(StrList *sp, const char *s)
850
855
{
851
 
        for (; sp; sp = sp->next)
852
 
                if (!strcmp( sp->str, s ))
853
 
                        return True;
854
 
        return False;
 
856
    for (; sp; sp = sp->next)
 
857
        if (!strcmp(sp->str, s))
 
858
            return True;
 
859
    return False;
855
860
}
856
861
 
857
862
static void
858
 
addStr( StrList **sp, const char *s )
 
863
addStr(StrList **sp, const char *s)
859
864
{
860
 
        for (; *sp; sp = &(*sp)->next)
861
 
                if (!strcmp( (*sp)->str, s ))
862
 
                        return;
863
 
        *sp = mcalloc( sizeof(**sp) );
864
 
        ASPrintf( (char **)&(*sp)->str, "%s", s );
 
865
    for (; *sp; sp = &(*sp)->next)
 
866
        if (!strcmp((*sp)->str, s))
 
867
            return;
 
868
    *sp = mcalloc(sizeof(**sp));
 
869
    ASPrintf((char **)&(*sp)->str, "%s", s);
865
870
}
866
871
 
867
872
static StrList *
868
 
splitList( const char *str )
 
873
splitList(const char *str)
869
874
{
870
 
        StrList *sp, **spp = &sp;
871
 
        const char *e;
872
 
        if (!*str)
873
 
                return 0;
874
 
        for (;;) {
875
 
                *spp = mcalloc( sizeof(**spp) );
876
 
                if (!(e = strchr( str, ',' )))
877
 
                        break;
878
 
                ASPrintf( (char **)&(*spp)->str, "%.*s", (int)(e - str), str );
879
 
                str = e + 1;
880
 
                spp = &(*spp)->next;
881
 
        }
882
 
        (*spp)->str = mstrdup( str );
883
 
        (*spp)->next = 0;
884
 
        return sp;
 
875
    StrList *sp, **spp = &sp;
 
876
    const char *e;
 
877
    if (!*str)
 
878
        return 0;
 
879
    for (;;) {
 
880
        *spp = mcalloc(sizeof(**spp));
 
881
        if (!(e = strchr(str, ',')))
 
882
            break;
 
883
        ASPrintf((char **)&(*spp)->str, "%.*s", (int)(e - str), str);
 
884
        str = e + 1;
 
885
        spp = &(*spp)->next;
 
886
    }
 
887
    (*spp)->str = mstrdup(str);
 
888
    (*spp)->next = 0;
 
889
    return sp;
885
890
}
886
891
 
887
892
static char *
888
 
joinList( StrList *sp )
 
893
joinList(StrList *sp)
889
894
{
890
 
        char *s = 0;
891
 
        if (!sp)
892
 
                return mstrdup( "" );
893
 
        s = mstrdup( sp->str );
894
 
        for (;;) {
895
 
                sp = sp->next;
896
 
                if (!sp)
897
 
                        return s;
898
 
                strCat( &s, ",%s", sp->str );
899
 
        }
 
895
    char *s = 0;
 
896
    if (!sp)
 
897
        return mstrdup("");
 
898
    s = mstrdup(sp->str);
 
899
    for (;;) {
 
900
        sp = sp->next;
 
901
        if (!sp)
 
902
            return s;
 
903
        strCat(&s, ",%s", sp->str);
 
904
    }
900
905
}
901
906
 
902
907
StrMap *cfmap;
904
909
 
905
910
/* file is part of new config */
906
911
static void
907
 
addedFile( const char *fn )
 
912
addedFile(const char *fn)
908
913
{
909
 
        addStr( &aflist, fn );
 
914
    addStr(&aflist, fn);
910
915
}
911
916
 
912
917
/* file from old config was parsed */
913
918
static void
914
 
usedFile( const char *fn )
 
919
usedFile(const char *fn)
915
920
{
916
 
        addStr( &uflist, fn );
 
921
    addStr(&uflist, fn);
917
922
}
918
923
 
919
924
/* file from old config was copied with slight modifications */
920
925
static void
921
 
editedFile( const char *fn )
 
926
editedFile(const char *fn)
922
927
{
923
 
        addStr( &eflist, fn );
 
928
    addStr(&eflist, fn);
924
929
}
925
930
 
926
931
/* file from old config was copied verbatim */
927
932
static void
928
 
copiedFile( const char *fn )
 
933
copiedFile(const char *fn)
929
934
{
930
 
        addStr( &cflist, fn );
 
935
    addStr(&cflist, fn);
931
936
}
932
937
 
933
938
/* file from old config is still being used */
934
939
static void
935
 
linkedFile( const char *fn )
 
940
linkedFile(const char *fn)
936
941
{
937
 
        addStr( &lflist, fn );
 
942
    addStr(&lflist, fn);
938
943
}
939
944
 
940
945
/*
946
951
 
947
952
/* Make a possibly modified copy of a file under KDMCONF */
948
953
static int
949
 
copyFile( Entry *ce, int mode, int (*proc)( File * ) )
 
954
copyFile(Entry *ce, int mode, int (*proc)(File *))
950
955
{
951
 
        const char *tptr;
952
 
        char *nname;
953
 
        File file;
954
 
        int rt;
955
 
 
956
 
        if (!*ce->value)
957
 
                return True;
958
 
 
959
 
        if ((nname = (char *)getMapping( cfmap, ce->value ))) {
960
 
                rt = inList( aflist, nname );
961
 
                goto doret;
962
 
        }
963
 
        if (oldkde) {
964
 
                int olen = strlen( oldkde );
965
 
                if (!memcmp( ce->value, oldkde, olen )) {
966
 
                        if (!memcmp( ce->value + olen, "/kdm/", 5 )) {
967
 
                                tptr = ce->value + olen + 4;
968
 
                                goto gotn;
969
 
                        }
970
 
                        if (ce->value[olen] == '/') {
971
 
                                tptr = ce->value + olen;
972
 
                                goto gotn;
973
 
                        }
974
 
                }
975
 
        }
976
 
        if (oldxdm) {
977
 
                int olen = strlen( oldxdm );
978
 
                if (!memcmp( ce->value, oldxdm, olen ) && ce->value[olen] == '/') {
979
 
                        tptr = ce->value + olen;
980
 
                        goto gotn;
981
 
                }
982
 
        }
983
 
        if (!(tptr = strrchr( ce->value, '/' ))) {
984
 
                fprintf( stderr, "Warning: cannot cope with relative path %s\n", ce->value );
985
 
                return False;
986
 
        }
 
956
    const char *tptr;
 
957
    char *nname;
 
958
    File file;
 
959
    int rt;
 
960
 
 
961
    if (!*ce->value)
 
962
        return True;
 
963
 
 
964
    if ((nname = (char *)getMapping(cfmap, ce->value))) {
 
965
        rt = inList(aflist, nname);
 
966
        goto doret;
 
967
    }
 
968
    if (oldkde) {
 
969
        int olen = strlen(oldkde);
 
970
        if (!memcmp(ce->value, oldkde, olen)) {
 
971
            if (!memcmp(ce->value + olen, "/kdm/", 5)) {
 
972
                tptr = ce->value + olen + 4;
 
973
                goto gotn;
 
974
            }
 
975
            if (ce->value[olen] == '/') {
 
976
                tptr = ce->value + olen;
 
977
                goto gotn;
 
978
            }
 
979
        }
 
980
    }
 
981
    if (oldxdm) {
 
982
        int olen = strlen(oldxdm);
 
983
        if (!memcmp(ce->value, oldxdm, olen) && ce->value[olen] == '/') {
 
984
            tptr = ce->value + olen;
 
985
            goto gotn;
 
986
        }
 
987
    }
 
988
    if (!(tptr = strrchr(ce->value, '/'))) {
 
989
        fprintf(stderr, "Warning: cannot cope with relative path %s\n", ce->value);
 
990
        return False;
 
991
    }
987
992
  gotn:
988
 
        ASPrintf( &nname, KDMCONF "%s", tptr );
989
 
        if (inList( aflist, nname )) {
990
 
                int cnt = 1;
991
 
                do {
992
 
                        free( nname );
993
 
                        ASPrintf( &nname, KDMCONF "%s-%d", tptr , ++cnt );
994
 
                } while (inList( aflist, nname ));
995
 
        }
996
 
        addMapping( &cfmap, ce->value, nname );
997
 
        if (!readFile( &file, ce->value )) {
998
 
                fprintf( stderr, "Warning: cannot copy file %s\n", ce->value );
999
 
                rt = False;
1000
 
        } else {
1001
 
                if (!proc || !proc( &file )) {
1002
 
                        if (!use_destdir && !strcmp( ce->value, nname ))
1003
 
                                linkedFile( nname );
1004
 
                        else {
1005
 
                                struct stat st;
1006
 
                                stat( ce->value, &st );
1007
 
                                writeCopy( nname + sizeof(KDMCONF), mode, st.st_mtime,
1008
 
                                           file.buf, file.eof - file.buf );
1009
 
                                copiedFile( ce->value );
1010
 
                        }
1011
 
                } else {
1012
 
                        writeCopy( nname + sizeof(KDMCONF), mode, 0,
1013
 
                                   file.buf, file.eof - file.buf );
1014
 
                        editedFile( ce->value );
1015
 
                }
1016
 
                if (strcmp( ce->value, nname ) && inNewDir( ce->value ) && !use_destdir)
1017
 
                        displace( ce->value );
1018
 
                addedFile( nname );
1019
 
                rt = True;
1020
 
        }
 
993
    ASPrintf(&nname, KDMCONF "%s", tptr);
 
994
    if (inList(aflist, nname)) {
 
995
        int cnt = 1;
 
996
        do {
 
997
            free(nname);
 
998
            ASPrintf(&nname, KDMCONF "%s-%d", tptr , ++cnt);
 
999
        } while (inList(aflist, nname));
 
1000
    }
 
1001
    addMapping(&cfmap, ce->value, nname);
 
1002
    if (!readFile(&file, ce->value)) {
 
1003
        fprintf(stderr, "Warning: cannot copy file %s\n", ce->value);
 
1004
        rt = False;
 
1005
    } else {
 
1006
        if (!proc || !proc(&file)) {
 
1007
            if (!use_destdir && !strcmp(ce->value, nname)) {
 
1008
                linkedFile(nname);
 
1009
            } else {
 
1010
                struct stat st;
 
1011
                stat(ce->value, &st);
 
1012
                writeCopy(nname + sizeof(KDMCONF), mode, st.st_mtime,
 
1013
                          file.buf, file.eof - file.buf);
 
1014
                copiedFile(ce->value);
 
1015
            }
 
1016
        } else {
 
1017
            writeCopy(nname + sizeof(KDMCONF), mode, 0,
 
1018
                      file.buf, file.eof - file.buf);
 
1019
            editedFile(ce->value);
 
1020
        }
 
1021
        if (strcmp(ce->value, nname) && inNewDir(ce->value) && !use_destdir)
 
1022
            displace(ce->value);
 
1023
        addedFile(nname);
 
1024
        rt = True;
 
1025
    }
1021
1026
  doret:
1022
 
        ce->value = nname;
1023
 
        return rt;
 
1027
    ce->value = nname;
 
1028
    return rt;
1024
1029
}
1025
1030
 
1026
1031
static void
1027
 
doLinkFile( const char *name )
 
1032
doLinkFile(const char *name)
1028
1033
{
1029
 
        File file;
 
1034
    File file;
1030
1035
 
1031
 
        if (inList( aflist, name ))
1032
 
                return;
1033
 
        if (!readFile( &file, name )) {
1034
 
                fprintf( stderr, "Warning: cannot read file %s\n", name );
1035
 
                return;
1036
 
        }
1037
 
        if (inNewDir( name ) && use_destdir) {
1038
 
                struct stat st;
1039
 
                stat( name, &st );
1040
 
                writeCopy( name + sizeof(KDMCONF), st.st_mode, st.st_mtime,
1041
 
                           file.buf, file.eof - file.buf );
1042
 
                copiedFile( name );
1043
 
        } else
1044
 
                linkedFile( name );
1045
 
        addedFile( name );
 
1036
    if (inList(aflist, name))
 
1037
        return;
 
1038
    if (!readFile(&file, name)) {
 
1039
        fprintf(stderr, "Warning: cannot read file %s\n", name);
 
1040
        return;
 
1041
    }
 
1042
    if (inNewDir(name) && use_destdir) {
 
1043
        struct stat st;
 
1044
        stat(name, &st);
 
1045
        writeCopy(name + sizeof(KDMCONF), st.st_mode, st.st_mtime,
 
1046
                  file.buf, file.eof - file.buf);
 
1047
        copiedFile(name);
 
1048
    } else {
 
1049
        linkedFile(name);
 
1050
    }
 
1051
    addedFile(name);
1046
1052
}
1047
1053
 
1048
1054
/* Incorporate an existing file */
1049
1055
static void
1050
 
linkFile( Entry *ce )
 
1056
linkFile(Entry *ce)
1051
1057
{
1052
 
        if (ce->written && *ce->value)
1053
 
                doLinkFile( ce->value );
 
1058
    if (ce->written && *ce->value)
 
1059
        doLinkFile(ce->value);
1054
1060
}
1055
1061
 
1056
1062
/* Create a new file in KDMCONF and fill it */
1057
1063
static void
1058
 
writeFile( const char *tname, int mode, const char *cont )
 
1064
writeFile(const char *tname, int mode, const char *cont)
1059
1065
{
1060
 
        FILE *f = createFile( tname + sizeof(KDMCONF), mode );
1061
 
        fputs_( cont, f );
1062
 
        fclose_( f );
1063
 
        addedFile( tname );
 
1066
    FILE *f = createFile(tname + sizeof(KDMCONF), mode);
 
1067
    fputs_(cont, f);
 
1068
    fclose_(f);
 
1069
    addedFile(tname);
1064
1070
}
1065
1071
 
1066
1072
 
1067
1073
static void
1068
 
handleBgCfg( Entry *ce, Section *cs )
 
1074
handleBgCfg(Entry *ce, Section *cs)
1069
1075
{
1070
 
        if (!ce->active) /* can be only the X-*-Greeter one */
1071
 
                writeFile( def_BackgroundCfg, 0644, def_background );
 
1076
    if (!ce->active) { /* can be only the X-*-Greeter one */
 
1077
        writeFile(def_BackgroundCfg, 0644, def_background);
1072
1078
#if 0 /* risk of kcontrol clobbering the original file */
1073
 
        else if (old_confs)
1074
 
                linkFile( ce );
 
1079
    } else if (old_confs) {
 
1080
        linkFile(ce);
1075
1081
#endif
1076
 
        else {
1077
 
                if (!copyFile( ce, 0644, 0 )) {
1078
 
                        if (!strcmp( cs->name, "X-*-Greeter" ))
1079
 
                                writeFile( def_BackgroundCfg, 0644, def_background );
1080
 
                        ce->active = False;
1081
 
                }
1082
 
        }
 
1082
    } else {
 
1083
        if (!copyFile(ce, 0644, 0)) {
 
1084
            if (!strcmp(cs->name, "X-*-Greeter"))
 
1085
                writeFile(def_BackgroundCfg, 0644, def_background);
 
1086
            ce->active = False;
 
1087
        }
 
1088
    }
1083
1089
}
1084
1090
 
1085
1091
 
1086
1092
#ifdef HAVE_VTS
1087
1093
static char *
1088
 
memMem( char *mem, int lmem, const char *smem, int lsmem )
 
1094
memMem(char *mem, int lmem, const char *smem, int lsmem)
1089
1095
{
1090
 
        for (; lmem >= lsmem; mem++, lmem--)
1091
 
                if (!memcmp( mem, smem, lsmem ))
1092
 
                        return mem + lsmem;
1093
 
        return 0;
 
1096
    for (; lmem >= lsmem; mem++, lmem--)
 
1097
        if (!memcmp(mem, smem, lsmem))
 
1098
            return mem + lsmem;
 
1099
    return 0;
1094
1100
}
1095
1101
 
1096
1102
static int maxTTY, TTYmask;
1097
1103
 
1098
1104
static void
1099
 
getInitTab( void )
 
1105
getInitTab(void)
1100
1106
{
1101
 
        File it;
1102
 
        char *p, *eol, *ep;
1103
 
        int tty;
 
1107
    File it;
 
1108
    char *p, *eol, *ep;
 
1109
    int tty;
1104
1110
 
1105
 
        if (maxTTY)
1106
 
                return;
1107
 
        if (readFile( &it, "/etc/inittab" )) {
1108
 
                usedFile( "/etc/inittab" );
1109
 
                for (p = it.buf; p < it.eof; p = eol + 1) {
1110
 
                        for (eol = p; eol < it.eof && *eol != '\n'; eol++);
1111
 
                        if (*p != '#') {
1112
 
                                if ((ep = memMem( p, eol - p, " tty", 4 )) &&
1113
 
                                    ep < eol && isdigit( *ep ))
1114
 
                                {
1115
 
                                        if (ep + 1 == eol || isspace( *(ep + 1) ))
1116
 
                                                tty = *ep - '0';
1117
 
                                        else if (isdigit( *(ep + 1) ) &&
1118
 
                                                 (ep + 2 == eol || isspace( *(ep + 2) )))
1119
 
                                                tty = (*ep - '0') * 10 + (*(ep + 1) - '0');
1120
 
                                        else
1121
 
                                                continue;
1122
 
                                        TTYmask |= 1 << (tty - 1);
1123
 
                                        if (tty > maxTTY)
1124
 
                                                maxTTY = tty;
1125
 
                                }
1126
 
                        }
1127
 
                }
1128
 
                freeBuf( &it );
1129
 
        }
1130
 
        if (!maxTTY) {
1131
 
                maxTTY = 6;
1132
 
                TTYmask = 0x3f;
1133
 
        }
 
1111
    if (maxTTY)
 
1112
        return;
 
1113
    if (readFile(&it, "/etc/inittab")) {
 
1114
        usedFile("/etc/inittab");
 
1115
        for (p = it.buf; p < it.eof; p = eol + 1) {
 
1116
            for (eol = p; eol < it.eof && *eol != '\n'; eol++);
 
1117
            if (*p != '#') {
 
1118
                if ((ep = memMem(p, eol - p, " tty", 4)) &&
 
1119
                    ep < eol && isdigit(*ep))
 
1120
                {
 
1121
                    if (ep + 1 == eol || isspace(*(ep + 1)))
 
1122
                        tty = *ep - '0';
 
1123
                    else if (isdigit(*(ep + 1)) &&
 
1124
                             (ep + 2 == eol || isspace(*(ep + 2))))
 
1125
                        tty = (*ep - '0') * 10 + (*(ep + 1) - '0');
 
1126
                    else
 
1127
                        continue;
 
1128
                    TTYmask |= 1 << (tty - 1);
 
1129
                    if (tty > maxTTY)
 
1130
                        maxTTY = tty;
 
1131
                }
 
1132
            }
 
1133
        }
 
1134
        freeBuf(&it);
 
1135
    }
 
1136
    if (!maxTTY) {
 
1137
        maxTTY = 6;
 
1138
        TTYmask = 0x3f;
 
1139
    }
1134
1140
}
1135
1141
#endif
1136
1142
 
1137
1143
 
1138
1144
static char *
1139
 
readWord( File *file, int EOFatEOL )
 
1145
readWord(File *file, int EOFatEOL)
1140
1146
{
1141
 
        char *wordp, *wordBuffer;
1142
 
        int quoted;
1143
 
        char c;
 
1147
    char *wordp, *wordBuffer;
 
1148
    int quoted;
 
1149
    char c;
1144
1150
 
1145
1151
  rest:
1146
 
        wordp = wordBuffer = file->cur;
 
1152
    wordp = wordBuffer = file->cur;
1147
1153
  mloop:
1148
 
        quoted = False;
 
1154
    quoted = False;
1149
1155
  qloop:
1150
 
        if (file->cur == file->eof) {
1151
 
          doeow:
1152
 
                if (wordp == wordBuffer)
1153
 
                        return 0;
1154
 
          retw:
1155
 
                *wordp = '\0';
1156
 
                return wordBuffer;
1157
 
        }
1158
 
        c = *file->cur++;
1159
 
        switch (c) {
1160
 
        case '#':
1161
 
                if (quoted)
1162
 
                        break;
1163
 
                do {
1164
 
                        if (file->cur == file->eof)
1165
 
                                goto doeow;
1166
 
                        c = *file->cur++;
1167
 
                } while (c != '\n');
1168
 
        case '\0':
1169
 
        case '\n':
1170
 
                if (EOFatEOL && !quoted) {
1171
 
                        file->cur--;
1172
 
                        goto doeow;
1173
 
                }
1174
 
                if (wordp != wordBuffer) {
1175
 
                        file->cur--;
1176
 
                        goto retw;
1177
 
                }
1178
 
                goto rest;
1179
 
        case ' ':
1180
 
        case '\t':
1181
 
                if (wordp != wordBuffer)
1182
 
                        goto retw;
1183
 
                goto rest;
1184
 
        case '\\':
1185
 
                if (!quoted) {
1186
 
                        quoted = True;
1187
 
                        goto qloop;
1188
 
                }
1189
 
                break;
1190
 
        }
1191
 
        *wordp++ = c;
1192
 
        goto mloop;
 
1156
    if (file->cur == file->eof) {
 
1157
      doeow:
 
1158
        if (wordp == wordBuffer)
 
1159
            return 0;
 
1160
      retw:
 
1161
        *wordp = '\0';
 
1162
        return wordBuffer;
 
1163
    }
 
1164
    c = *file->cur++;
 
1165
    switch (c) {
 
1166
    case '#':
 
1167
        if (quoted)
 
1168
            break;
 
1169
        do {
 
1170
            if (file->cur == file->eof)
 
1171
                goto doeow;
 
1172
            c = *file->cur++;
 
1173
        } while (c != '\n');
 
1174
    case '\0':
 
1175
    case '\n':
 
1176
        if (EOFatEOL && !quoted) {
 
1177
            file->cur--;
 
1178
            goto doeow;
 
1179
        }
 
1180
        if (wordp != wordBuffer) {
 
1181
            file->cur--;
 
1182
            goto retw;
 
1183
        }
 
1184
        goto rest;
 
1185
    case ' ':
 
1186
    case '\t':
 
1187
        if (wordp != wordBuffer)
 
1188
            goto retw;
 
1189
        goto rest;
 
1190
    case '\\':
 
1191
        if (!quoted) {
 
1192
            quoted = True;
 
1193
            goto qloop;
 
1194
        }
 
1195
        break;
 
1196
    }
 
1197
    *wordp++ = c;
 
1198
    goto mloop;
1193
1199
}
1194
1200
 
1195
1201
/* backslashes are double-escaped - first parseArgs, then KConfig */
1196
1202
 
1197
1203
static StrList *
1198
 
splitArgs( const char *string )
 
1204
splitArgs(const char *string)
1199
1205
{
1200
 
        const char *word;
1201
 
        char *str;
1202
 
        int wlen;
1203
 
        StrList *args, **argp = &args;
 
1206
    const char *word;
 
1207
    char *str;
 
1208
    int wlen;
 
1209
    StrList *args, **argp = &args;
1204
1210
 
1205
 
        while (*string) {
1206
 
                if (isspace( *string )) {
1207
 
                        string++;
1208
 
                        continue;
1209
 
                }
1210
 
                word = string;
1211
 
                wlen = 0;
1212
 
                do {
1213
 
                        if (*string == '\\') {
1214
 
                                if (*++string != '\\')
1215
 
                                        string--;
1216
 
                                if (*++string != '\\')
1217
 
                                        string--;
1218
 
                                if (!*++string)
1219
 
                                        string--;
1220
 
                                wlen++;
1221
 
                        } else if (*string == '\'') {
1222
 
                                while (*++string != '\'' && *string) {
1223
 
                                        if (*string == '\\' && *++string != '\\')
1224
 
                                                string--;
1225
 
                                        wlen++;
1226
 
                                }
1227
 
                        } else if (*string == '"') {
1228
 
                                while (*++string != '"' && *string) {
1229
 
                                        if (*string == '\\') {
1230
 
                                                if (*++string != '\\')
1231
 
                                                        string--;
1232
 
                                                if (*++string != '\\')
1233
 
                                                        string--;
1234
 
                                                if (!*++string)
1235
 
                                                        string--;
1236
 
                                        }
1237
 
                                        wlen++;
1238
 
                                }
1239
 
                        } else
1240
 
                                wlen++;
1241
 
                } while (*++string && !isspace( *string ));
1242
 
                *argp = mmalloc( sizeof(**argp) );
1243
 
                (*argp)->str = str = mmalloc( wlen + 1 );
1244
 
                do {
1245
 
                        if (*word == '\\') {
1246
 
                                if (*++word != '\\')
1247
 
                                        word--;
1248
 
                                if (*++word != '\\')
1249
 
                                        word--;
1250
 
                                if (!*++word)
1251
 
                                        word--;
1252
 
                                *str++ = *word;
1253
 
                        } else if (*word == '\'') {
1254
 
                                while (*++word != '\'' && *word) {
1255
 
                                        if (*word == '\\' && *++word != '\\')
1256
 
                                                word--;
1257
 
                                        *str++ = *word;
1258
 
                                }
1259
 
                        } else if (*word == '"') {
1260
 
                                while (*++word != '"' && *word) {
1261
 
                                        if (*word == '\\') {
1262
 
                                                if (*++word != '\\')
1263
 
                                                        word--;
1264
 
                                                if (*++word != '\\')
1265
 
                                                        word--;
1266
 
                                                if (!*++word)
1267
 
                                                        word--;
1268
 
                                        }
1269
 
                                        *str++ = *word;
1270
 
                                }
1271
 
                        } else
1272
 
                                *str++ = *word;
1273
 
                } while (*++word && !isspace( *word ));
1274
 
                *str = 0;
1275
 
                argp = &(*argp)->next;
1276
 
        }
1277
 
        *argp = 0;
1278
 
        return args;
 
1211
    while (*string) {
 
1212
        if (isspace(*string)) {
 
1213
            string++;
 
1214
            continue;
 
1215
        }
 
1216
        word = string;
 
1217
        wlen = 0;
 
1218
        do {
 
1219
            if (*string == '\\') {
 
1220
                if (*++string != '\\')
 
1221
                    string--;
 
1222
                if (*++string != '\\')
 
1223
                    string--;
 
1224
                if (!*++string)
 
1225
                    string--;
 
1226
                wlen++;
 
1227
            } else if (*string == '\'') {
 
1228
                while (*++string != '\'' && *string) {
 
1229
                    if (*string == '\\' && *++string != '\\')
 
1230
                        string--;
 
1231
                    wlen++;
 
1232
                }
 
1233
            } else if (*string == '"') {
 
1234
                while (*++string != '"' && *string) {
 
1235
                    if (*string == '\\') {
 
1236
                        if (*++string != '\\')
 
1237
                            string--;
 
1238
                        if (*++string != '\\')
 
1239
                            string--;
 
1240
                        if (!*++string)
 
1241
                            string--;
 
1242
                    }
 
1243
                    wlen++;
 
1244
                }
 
1245
            } else {
 
1246
                wlen++;
 
1247
            }
 
1248
        } while (*++string && !isspace(*string));
 
1249
        *argp = mmalloc(sizeof(**argp));
 
1250
        (*argp)->str = str = mmalloc(wlen + 1);
 
1251
        do {
 
1252
            if (*word == '\\') {
 
1253
                if (*++word != '\\')
 
1254
                    word--;
 
1255
                if (*++word != '\\')
 
1256
                    word--;
 
1257
                if (!*++word)
 
1258
                    word--;
 
1259
                *str++ = *word;
 
1260
            } else if (*word == '\'') {
 
1261
                while (*++word != '\'' && *word) {
 
1262
                    if (*word == '\\' && *++word != '\\')
 
1263
                        word--;
 
1264
                    *str++ = *word;
 
1265
                }
 
1266
            } else if (*word == '"') {
 
1267
                while (*++word != '"' && *word) {
 
1268
                    if (*word == '\\') {
 
1269
                        if (*++word != '\\')
 
1270
                            word--;
 
1271
                        if (*++word != '\\')
 
1272
                            word--;
 
1273
                        if (!*++word)
 
1274
                            word--;
 
1275
                    }
 
1276
                    *str++ = *word;
 
1277
                }
 
1278
            } else {
 
1279
                *str++ = *word;
 
1280
            }
 
1281
        } while (*++word && !isspace(*word));
 
1282
        *str = 0;
 
1283
        argp = &(*argp)->next;
 
1284
    }
 
1285
    *argp = 0;
 
1286
    return args;
1279
1287
}
1280
1288
 
1281
1289
static const char *
1282
 
joinArgs( StrList *argv )
 
1290
joinArgs(StrList *argv)
1283
1291
{
1284
 
        StrList *av;
1285
 
        const char *s, *rs;
1286
 
        char *str;
1287
 
        int slen;
 
1292
    StrList *av;
 
1293
    const char *s, *rs;
 
1294
    char *str;
 
1295
    int slen;
1288
1296
 
1289
 
        if (!argv)
1290
 
                return "";
1291
 
        for (slen = 0, av = argv; slen++, av; av = av->next) {
1292
 
                int nq = 0;
1293
 
                for (s = av->str; *s; s++, slen++)
1294
 
                        if (isspace( *s ) || *s == '\'')
1295
 
                                nq = 2;
1296
 
                        else if (*s == '"')
1297
 
                                slen += 2;
1298
 
                        else if (*s == '\\')
1299
 
                                slen += 3;
1300
 
                slen += nq;
1301
 
        }
1302
 
        rs = str = mmalloc( slen );
1303
 
        for (av = argv; av; av = av->next) {
1304
 
                int nq = 0;
1305
 
                for (s = av->str; *s; s++)
1306
 
                        if (isspace( *s ) || *s == '\'')
1307
 
                                nq = 2;
1308
 
                if (av != argv)
1309
 
                        *str++ = ' ';
1310
 
                if (nq)
1311
 
                        *str++ = '"';
1312
 
                for (s = av->str; *s; s++) {
1313
 
                        if (*s == '\\')
1314
 
                                *str++ = '\\';
1315
 
                        if (*s == '"' || *s == '\\') {
1316
 
                                *str++ = '\\';
1317
 
                                *str++ = '\\';
1318
 
                        }
1319
 
                        *str++ = *s;
1320
 
                }
1321
 
                if (nq)
1322
 
                        *str++ = '"';
1323
 
        }
1324
 
        *str = 0;
1325
 
        return rs;
 
1297
    if (!argv)
 
1298
        return "";
 
1299
    for (slen = 0, av = argv; slen++, av; av = av->next) {
 
1300
        int nq = 0;
 
1301
        for (s = av->str; *s; s++, slen++)
 
1302
            if (isspace(*s) || *s == '\'')
 
1303
                nq = 2;
 
1304
            else if (*s == '"')
 
1305
                slen += 2;
 
1306
            else if (*s == '\\')
 
1307
                slen += 3;
 
1308
        slen += nq;
 
1309
    }
 
1310
    rs = str = mmalloc(slen);
 
1311
    for (av = argv; av; av = av->next) {
 
1312
        int nq = 0;
 
1313
        for (s = av->str; *s; s++)
 
1314
            if (isspace(*s) || *s == '\'')
 
1315
                nq = 2;
 
1316
        if (av != argv)
 
1317
            *str++ = ' ';
 
1318
        if (nq)
 
1319
            *str++ = '"';
 
1320
        for (s = av->str; *s; s++) {
 
1321
            if (*s == '\\')
 
1322
                *str++ = '\\';
 
1323
            if (*s == '"' || *s == '\\') {
 
1324
                *str++ = '\\';
 
1325
                *str++ = '\\';
 
1326
            }
 
1327
            *str++ = *s;
 
1328
        }
 
1329
        if (nq)
 
1330
            *str++ = '"';
 
1331
    }
 
1332
    *str = 0;
 
1333
    return rs;
1326
1334
}
1327
1335
 
1328
1336
typedef enum { InvalidDpy, LocalDpy, LocalUidDpy, ForeignDpy } DisplayMatchType;
1329
1337
 
1330
1338
static struct displayMatch {
1331
 
        const char *name;
1332
 
        int len;
1333
 
        DisplayMatchType type;
 
1339
    const char *name;
 
1340
    int len;
 
1341
    DisplayMatchType type;
1334
1342
} displayTypes[] = {
1335
 
        { "local", 5, LocalDpy },
1336
 
        { "local_uid", 9, LocalUidDpy },
1337
 
        { "foreign", 7, ForeignDpy },
 
1343
    { "local", 5, LocalDpy },
 
1344
    { "local_uid", 9, LocalUidDpy },
 
1345
    { "foreign", 7, ForeignDpy },
1338
1346
};
1339
1347
 
1340
1348
static DisplayMatchType
1341
 
parseDisplayType( const char *string, const char **atPos )
 
1349
parseDisplayType(const char *string, const char **atPos)
1342
1350
{
1343
 
        struct displayMatch *d;
 
1351
    struct displayMatch *d;
1344
1352
 
1345
 
        *atPos = 0;
1346
 
        for (d = displayTypes; d < displayTypes + as(displayTypes); d++) {
1347
 
                if (!memcmp( d->name, string, d->len ) &&
1348
 
                    (!string[d->len] || string[d->len] == '@'))
1349
 
                {
1350
 
                        if (string[d->len] == '@' && string[d->len + 1])
1351
 
                                *atPos = string + d->len + 1;
1352
 
                        return d->type;
1353
 
                }
1354
 
        }
1355
 
        return InvalidDpy;
 
1353
    *atPos = 0;
 
1354
    for (d = displayTypes; d < displayTypes + as(displayTypes); d++) {
 
1355
        if (!memcmp(d->name, string, d->len) &&
 
1356
            (!string[d->len] || string[d->len] == '@'))
 
1357
        {
 
1358
            if (string[d->len] == '@' && string[d->len + 1])
 
1359
                *atPos = string + d->len + 1;
 
1360
            return d->type;
 
1361
        }
 
1362
    }
 
1363
    return InvalidDpy;
1356
1364
}
1357
1365
 
1358
1366
typedef struct serverEntry {
1359
 
        struct serverEntry *next;
1360
 
        const char *name, *class2, *console, *owner, *argvs, *arglvs;
1361
 
        StrList *argv, *arglv;
1362
 
        DisplayMatchType type;
1363
 
        int reserve, vt;
 
1367
    struct serverEntry *next;
 
1368
    const char *name, *class2, *console, *owner, *argvs, *arglvs;
 
1369
    StrList *argv, *arglv;
 
1370
    DisplayMatchType type;
 
1371
    int reserve, vt;
1364
1372
} ServerEntry;
1365
1373
 
1366
1374
static int
1367
 
mstrcmp( const char *s1, const char *s2 )
 
1375
mstrcmp(const char *s1, const char *s2)
1368
1376
{
1369
 
        if (s1 == s2)
1370
 
                return 0;
1371
 
        if (!s1)
1372
 
                return -1;
1373
 
        if (!s2)
1374
 
                return 1;
1375
 
        return strcmp( s1, s2 );
 
1377
    if (s1 == s2)
 
1378
        return 0;
 
1379
    if (!s1)
 
1380
        return -1;
 
1381
    if (!s2)
 
1382
        return 1;
 
1383
    return strcmp(s1, s2);
1376
1384
}
1377
1385
 
1378
1386
static void
1379
 
absorbXservers( const char *sect ATTR_UNUSED, char **value )
 
1387
absorbXservers(const char *sect ATTR_UNUSED, char **value)
1380
1388
{
1381
 
        ServerEntry *se, *se1, *serverList, **serverPtr;
1382
 
        const char *word, *word2;
1383
 
        char *sdpys, *rdpys;
1384
 
        StrList **argp, **arglp, *ap, *ap2;
1385
 
        File file;
1386
 
        int nldpys = 0, nrdpys = 0, dpymask = 0;
1387
 
        int cpuid, cpcmd, cpcmdl;
 
1389
    ServerEntry *se, *se1, *serverList, **serverPtr;
 
1390
    const char *word, *word2;
 
1391
    char *sdpys, *rdpys;
 
1392
    StrList **argp, **arglp, *ap, *ap2;
 
1393
    File file;
 
1394
    int nldpys = 0, nrdpys = 0, dpymask = 0;
 
1395
    int cpuid, cpcmd, cpcmdl;
1388
1396
#ifdef HAVE_VTS
1389
 
        int dn, cpvt, mtty;
 
1397
    int dn, cpvt, mtty;
1390
1398
#endif
1391
1399
 
1392
 
        if (**value == '/') {
1393
 
                if (!readFile( &file, *value ))
1394
 
                        return;
1395
 
                usedFile( *value );
1396
 
        } else {
1397
 
                file.buf = *value;
1398
 
                file.eof = *value + strlen( *value );
1399
 
        }
1400
 
        file.cur = file.buf;
 
1400
    if (**value == '/') {
 
1401
        if (!readFile(&file, *value))
 
1402
            return;
 
1403
        usedFile(*value);
 
1404
    } else {
 
1405
        file.buf = *value;
 
1406
        file.eof = *value + strlen(*value);
 
1407
    }
 
1408
    file.cur = file.buf;
1401
1409
 
1402
 
        serverPtr = &serverList;
 
1410
    serverPtr = &serverList;
1403
1411
#ifdef HAVE_VTS
1404
1412
  bustd:
1405
1413
#endif
1406
 
        while ((word = readWord( &file, 0 ))) {
1407
 
                se = mcalloc( sizeof(*se) );
1408
 
                se->name = word;
1409
 
                if (!(word = readWord( &file, 1 )))
1410
 
                        continue;
1411
 
                se->type = parseDisplayType( word, &se->console );
1412
 
                if (se->type == InvalidDpy) {
1413
 
                        se->class2 = word;
1414
 
                        if (!(word = readWord( &file, 1 )))
1415
 
                                continue;
1416
 
                        se->type = parseDisplayType( word, &se->console );
1417
 
                        if (se->type == InvalidDpy) {
1418
 
                                while (readWord( &file, 1 ));
1419
 
                                continue;
1420
 
                        }
1421
 
                }
1422
 
                if (se->type == LocalUidDpy)
1423
 
                        if (!(se->owner = readWord( &file, 1 )))
1424
 
                                continue;
1425
 
                word = readWord( &file, 1 );
1426
 
                if (word && !strcmp( word, "reserve" )) {
1427
 
                        se->reserve = True;
1428
 
                        word = readWord( &file, 1 );
1429
 
                }
1430
 
                if ((se->type != ForeignDpy) != (word != 0))
1431
 
                        continue;
1432
 
                argp = &se->argv;
1433
 
                arglp = &se->arglv;
1434
 
                while (word) {
1435
 
#ifdef HAVE_VTS
1436
 
                        if (word[0] == 'v' && word[1] == 't')
1437
 
                                se->vt = atoi( word + 2 );
1438
 
                        else if (!strcmp( word, "-crt" )) { /* SCO style */
1439
 
                                if (!(word = readWord( &file, 1 )) ||
1440
 
                                    memcmp( word, "/dev/tty", 8 ))
1441
 
                                        goto bustd;
1442
 
                                se->vt = atoi( word + 8 );
1443
 
                        } else
1444
 
#endif
1445
 
                        if (strcmp( word, se->name )) {
1446
 
                                ap = mmalloc( sizeof(*ap) );
1447
 
                                ap->str = word;
1448
 
                                if (!strcmp( word, "-nolisten" )) {
1449
 
                                        if (!(word2 = readWord( &file, 1 )))
1450
 
                                                break;
1451
 
                                        ap2 = mmalloc( sizeof(*ap2) );
1452
 
                                        ap2->str = word2;
1453
 
                                        ap->next = ap2;
1454
 
                                        if (!strcmp( word2, "unix" )) {
1455
 
                                                *argp = ap;
1456
 
                                                argp = &ap2->next;
1457
 
                                        } else {
1458
 
                                                *arglp = ap;
1459
 
                                                arglp = &ap2->next;
1460
 
                                        }
1461
 
                                } else {
1462
 
                                        *argp = ap;
1463
 
                                        argp = &ap->next;
1464
 
                                }
1465
 
                        }
1466
 
                        word = readWord( &file, 1 );
1467
 
                }
1468
 
                *argp = *arglp = 0;
1469
 
                if (se->type != ForeignDpy) {
1470
 
                        nldpys++;
1471
 
                        dpymask |= 1 << atoi( se->name + 1 );
1472
 
                        if (se->reserve)
1473
 
                                nrdpys++;
1474
 
                }
1475
 
                *serverPtr = se;
1476
 
                serverPtr = &se->next;
1477
 
        }
1478
 
        *serverPtr = 0;
1479
 
 
1480
 
#ifdef HAVE_VTS
1481
 
        /* don't copy only if all local displays are ordered and have a vt */
1482
 
        cpvt = False;
1483
 
        getInitTab();
1484
 
        for (se = serverList, mtty = maxTTY; se; se = se->next)
1485
 
                if (se->type != ForeignDpy) {
1486
 
                        mtty++;
1487
 
                        if (se->vt != mtty) {
1488
 
                                cpvt = True;
1489
 
                                break;
1490
 
                        }
1491
 
                }
1492
 
#endif
1493
 
 
1494
 
        for (se = serverList; se; se = se->next) {
1495
 
                se->argvs = joinArgs( se->argv );
1496
 
                se->arglvs = joinArgs( se->arglv );
1497
 
        }
1498
 
 
1499
 
        se1 = 0, cpuid = cpcmd = cpcmdl = False;
1500
 
        for (se = serverList; se; se = se->next)
1501
 
                if (se->type != ForeignDpy) {
1502
 
                        if (!se1)
1503
 
                                se1 = se;
1504
 
                        else {
1505
 
                                if (strcmp( se1->argvs, se->argvs ))
1506
 
                                        cpcmd = True;
1507
 
                                if (strcmp( se1->arglvs, se->arglvs ))
1508
 
                                        cpcmdl = True;
1509
 
                                if (mstrcmp( se1->owner, se->owner ))
1510
 
                                        cpuid = True;
1511
 
                        }
1512
 
                }
1513
 
        if (se1) {
1514
 
                putFqVal( "X-:*-Core", "ServerCmd", se1->argvs );
1515
 
                if (se1->owner)
1516
 
                        putFqVal( "X-:*-Core", "ServerUID", se1->owner );
1517
 
                putFqVal( "X-:*-Core", "ServerArgsLocal", se1->arglvs );
1518
 
                for (se = serverList; se; se = se->next)
1519
 
                        if (se->type != ForeignDpy) {
1520
 
                                char sec[32];
1521
 
                                sprintf( sec, "X-%s-Core", se->name );
1522
 
                                if (cpcmd)
1523
 
                                        putFqVal( sec, "ServerCmd", se->argvs );
1524
 
                                if (cpcmdl)
1525
 
                                        putFqVal( sec, "ServerArgsLocal", se->arglvs );
1526
 
#ifdef HAVE_VTS
1527
 
                                if (cpvt && se->vt) {
1528
 
                                        char vt[8];
1529
 
                                        sprintf( vt, "%d", se->vt );
1530
 
                                        putFqVal( sec, "ServerVT", vt );
1531
 
                                }
 
1414
    while ((word = readWord(&file, 0))) {
 
1415
        se = mcalloc(sizeof(*se));
 
1416
        se->name = word;
 
1417
        if (!(word = readWord(&file, 1)))
 
1418
            continue;
 
1419
        se->type = parseDisplayType(word, &se->console);
 
1420
        if (se->type == InvalidDpy) {
 
1421
            se->class2 = word;
 
1422
            if (!(word = readWord(&file, 1)))
 
1423
                continue;
 
1424
            se->type = parseDisplayType(word, &se->console);
 
1425
            if (se->type == InvalidDpy) {
 
1426
                while (readWord(&file, 1));
 
1427
                continue;
 
1428
            }
 
1429
        }
 
1430
        if (se->type == LocalUidDpy)
 
1431
            if (!(se->owner = readWord(&file, 1)))
 
1432
                continue;
 
1433
        word = readWord(&file, 1);
 
1434
        if (word && !strcmp(word, "reserve")) {
 
1435
            se->reserve = True;
 
1436
            word = readWord(&file, 1);
 
1437
        }
 
1438
        if ((se->type != ForeignDpy) != (word != 0))
 
1439
            continue;
 
1440
        argp = &se->argv;
 
1441
        arglp = &se->arglv;
 
1442
        while (word) {
 
1443
#ifdef HAVE_VTS
 
1444
            if (word[0] == 'v' && word[1] == 't') {
 
1445
                se->vt = atoi(word + 2);
 
1446
            } else if (!strcmp(word, "-crt")) { /* SCO style */
 
1447
                if (!(word = readWord(&file, 1)) || memcmp(word, "/dev/tty", 8))
 
1448
                    goto bustd;
 
1449
                se->vt = atoi(word + 8);
 
1450
            } else
 
1451
#endif
 
1452
            if (strcmp(word, se->name)) {
 
1453
                ap = mmalloc(sizeof(*ap));
 
1454
                ap->str = word;
 
1455
                if (!strcmp(word, "-nolisten")) {
 
1456
                    if (!(word2 = readWord(&file, 1)))
 
1457
                        break;
 
1458
                    ap2 = mmalloc(sizeof(*ap2));
 
1459
                    ap2->str = word2;
 
1460
                    ap->next = ap2;
 
1461
                    if (!strcmp(word2, "unix")) {
 
1462
                        *argp = ap;
 
1463
                        argp = &ap2->next;
 
1464
                    } else {
 
1465
                        *arglp = ap;
 
1466
                        arglp = &ap2->next;
 
1467
                    }
 
1468
                } else {
 
1469
                    *argp = ap;
 
1470
                    argp = &ap->next;
 
1471
                }
 
1472
            }
 
1473
            word = readWord(&file, 1);
 
1474
        }
 
1475
        *argp = *arglp = 0;
 
1476
        if (se->type != ForeignDpy) {
 
1477
            nldpys++;
 
1478
            dpymask |= 1 << atoi(se->name + 1);
 
1479
            if (se->reserve)
 
1480
                nrdpys++;
 
1481
        }
 
1482
        *serverPtr = se;
 
1483
        serverPtr = &se->next;
 
1484
    }
 
1485
    *serverPtr = 0;
 
1486
 
 
1487
#ifdef HAVE_VTS
 
1488
    /* don't copy only if all local displays are ordered and have a vt */
 
1489
    cpvt = False;
 
1490
    getInitTab();
 
1491
    for (se = serverList, mtty = maxTTY; se; se = se->next)
 
1492
        if (se->type != ForeignDpy) {
 
1493
            mtty++;
 
1494
            if (se->vt != mtty) {
 
1495
                cpvt = True;
 
1496
                break;
 
1497
            }
 
1498
        }
 
1499
#endif
 
1500
 
 
1501
    for (se = serverList; se; se = se->next) {
 
1502
        se->argvs = joinArgs(se->argv);
 
1503
        se->arglvs = joinArgs(se->arglv);
 
1504
    }
 
1505
 
 
1506
    se1 = 0, cpuid = cpcmd = cpcmdl = False;
 
1507
    for (se = serverList; se; se = se->next)
 
1508
        if (se->type != ForeignDpy) {
 
1509
            if (!se1) {
 
1510
                se1 = se;
 
1511
            } else {
 
1512
                if (strcmp(se1->argvs, se->argvs))
 
1513
                    cpcmd = True;
 
1514
                if (strcmp(se1->arglvs, se->arglvs))
 
1515
                    cpcmdl = True;
 
1516
                if (mstrcmp(se1->owner, se->owner))
 
1517
                    cpuid = True;
 
1518
            }
 
1519
        }
 
1520
    if (se1) {
 
1521
        putFqVal("X-:*-Core", "ServerCmd", se1->argvs);
 
1522
        if (se1->owner)
 
1523
            putFqVal("X-:*-Core", "ServerUID", se1->owner);
 
1524
        putFqVal("X-:*-Core", "ServerArgsLocal", se1->arglvs);
 
1525
        for (se = serverList; se; se = se->next)
 
1526
            if (se->type != ForeignDpy) {
 
1527
                char sec[32];
 
1528
                sprintf(sec, "X-%s-Core", se->name);
 
1529
                if (cpcmd)
 
1530
                    putFqVal(sec, "ServerCmd", se->argvs);
 
1531
                if (cpcmdl)
 
1532
                    putFqVal(sec, "ServerArgsLocal", se->arglvs);
 
1533
#ifdef HAVE_VTS
 
1534
                if (cpvt && se->vt) {
 
1535
                    char vt[8];
 
1536
                    sprintf(vt, "%d", se->vt);
 
1537
                    putFqVal(sec, "ServerVT", vt);
 
1538
                }
1532
1539
#else
1533
 
                                if (se->console)
1534
 
                                        putFqVal( sec, "ServerTTY", se->console );
1535
 
#endif
1536
 
                                if (cpuid && se->owner)
1537
 
                                        putFqVal( sec, "ServerUID", se->owner );
1538
 
                        }
1539
 
        }
1540
 
 
1541
 
        sdpys = rdpys = 0;
1542
 
        for (se = serverList; se; se = se->next)
1543
 
                strCat( se->reserve ? &rdpys : &sdpys,
1544
 
                        se->class2 ? ",%s_%s" : ",%s", se->name, se->class2 );
1545
 
 
1546
 
#ifdef HAVE_VTS
1547
 
        /* add reserve dpys */
1548
 
        if (nldpys < 4 && nldpys && !nrdpys)
1549
 
                for (; nldpys < 4; nldpys++) {
1550
 
                        for (dn = 0; dpymask & (1 << dn); dn++);
1551
 
                        dpymask |= (1 << dn);
1552
 
                        strCat( &rdpys, ",:%d", dn );
1553
 
                }
1554
 
#endif
1555
 
 
1556
 
        putFqVal( "General", "StaticServers", sdpys ? sdpys + 1 : "" );
1557
 
        putFqVal( "General", "ReserveServers", rdpys ? rdpys + 1 : "" );
1558
 
 
1559
 
        if (**value == '/' && inNewDir( *value ) && !use_destdir)
1560
 
                displace( *value );
1561
 
}
1562
 
 
1563
 
#ifdef HAVE_VTS
1564
 
static void
1565
 
upd_servervts( Entry *ce, Section *cs ATTR_UNUSED )
1566
 
{
1567
 
        if (!ce->active) { /* there is only the Global one */
1568
 
#ifdef __linux__ /* XXX actually, sysvinit */
1569
 
                getInitTab();
1570
 
                ASPrintf( (char **)&ce->value, "-%d", maxTTY + 1 );
1571
 
                ce->active = ce->written = True;
1572
 
#endif
1573
 
        }
1574
 
}
1575
 
 
1576
 
static void
1577
 
upd_consolettys( Entry *ce, Section *cs ATTR_UNUSED )
1578
 
{
1579
 
        if (!ce->active) { /* there is only the Global one */
1580
 
#ifdef __linux__ /* XXX actually, sysvinit */
1581
 
                char *buf;
1582
 
                int i;
1583
 
 
1584
 
                getInitTab();
1585
 
                for (i = 0, buf = 0; i < 16; i++)
1586
 
                        if (TTYmask & (1 << i))
1587
 
                                strCat( &buf, ",tty%d", i + 1 );
1588
 
                if (buf) {
1589
 
                        ce->value = buf + 1;
1590
 
                        ce->active = ce->written = True;
1591
 
                }
1592
 
#endif
1593
 
        }
1594
 
}
1595
 
#endif
1596
 
 
1597
 
static void
1598
 
upd_servercmd( Entry *ce, Section *cs ATTR_UNUSED )
1599
 
{
1600
 
        StrList *sa;
1601
 
        FILE *fp;
1602
 
        char *svr;
1603
 
        char buf[20000];
1604
 
 
1605
 
        if (!ce->active || oldver >= 0x0204)
1606
 
                return;
1607
 
        if (!(sa = splitArgs( ce->value )))
1608
 
                return;
1609
 
        ASPrintf( &svr, "%s -help 2>&1", sa->str );
1610
 
        if (!(fp = popen( svr, "r" )))
1611
 
                return;
1612
 
        buf[fread( buf, 1, sizeof(buf) - 1, fp )] = 0;
1613
 
        pclose( fp );
1614
 
        if (strstr( buf, "\n-br " ))
1615
 
                addStr( &sa, "-br" );
1616
 
        if (strstr( buf, "\n-novtswitch " ))
1617
 
                addStr( &sa, "-novtswitch" );
1618
 
        if (strstr( buf, "\n-quiet " ))
1619
 
                addStr( &sa, "-quiet" );
1620
 
        ce->value = joinArgs( sa );
1621
 
        ce->written = True;
 
1540
                if (se->console)
 
1541
                    putFqVal(sec, "ServerTTY", se->console);
 
1542
#endif
 
1543
                if (cpuid && se->owner)
 
1544
                    putFqVal(sec, "ServerUID", se->owner);
 
1545
            }
 
1546
    }
 
1547
 
 
1548
    sdpys = rdpys = 0;
 
1549
    for (se = serverList; se; se = se->next)
 
1550
        strCat(se->reserve ? &rdpys : &sdpys,
 
1551
               se->class2 ? ",%s_%s" : ",%s", se->name, se->class2);
 
1552
 
 
1553
#ifdef HAVE_VTS
 
1554
    /* add reserve dpys */
 
1555
    if (nldpys < 4 && nldpys && !nrdpys)
 
1556
        for (; nldpys < 4; nldpys++) {
 
1557
            for (dn = 0; dpymask & (1 << dn); dn++);
 
1558
            dpymask |= (1 << dn);
 
1559
            strCat(&rdpys, ",:%d", dn);
 
1560
        }
 
1561
#endif
 
1562
 
 
1563
    putFqVal("General", "StaticServers", sdpys ? sdpys + 1 : "");
 
1564
    putFqVal("General", "ReserveServers", rdpys ? rdpys + 1 : "");
 
1565
 
 
1566
    if (**value == '/' && inNewDir(*value) && !use_destdir)
 
1567
        displace(*value);
 
1568
}
 
1569
 
 
1570
#ifdef HAVE_VTS
 
1571
static void
 
1572
upd_servervts(Entry *ce, Section *cs ATTR_UNUSED)
 
1573
{
 
1574
    if (!ce->active) { /* there is only the Global one */
 
1575
#ifdef __linux__ /* XXX actually, sysvinit */
 
1576
        getInitTab();
 
1577
        ASPrintf((char **)&ce->value, "-%d", maxTTY + 1);
 
1578
        ce->active = ce->written = True;
 
1579
#endif
 
1580
    }
 
1581
}
 
1582
 
 
1583
static void
 
1584
upd_consolettys(Entry *ce, Section *cs ATTR_UNUSED)
 
1585
{
 
1586
    if (!ce->active) { /* there is only the Global one */
 
1587
#ifdef __linux__ /* XXX actually, sysvinit */
 
1588
        char *buf;
 
1589
        int i;
 
1590
 
 
1591
        getInitTab();
 
1592
        for (i = 0, buf = 0; i < 16; i++)
 
1593
            if (TTYmask & (1 << i))
 
1594
                strCat(&buf, ",tty%d", i + 1);
 
1595
        if (buf) {
 
1596
            ce->value = buf + 1;
 
1597
            ce->active = ce->written = True;
 
1598
        }
 
1599
#endif
 
1600
    }
 
1601
}
 
1602
#endif
 
1603
 
 
1604
static void
 
1605
upd_servercmd(Entry *ce, Section *cs ATTR_UNUSED)
 
1606
{
 
1607
    StrList *sa;
 
1608
    FILE *fp;
 
1609
    char *svr;
 
1610
    char buf[20000];
 
1611
 
 
1612
    if (!ce->active || oldver >= 0x0204)
 
1613
        return;
 
1614
    if (!(sa = splitArgs(ce->value)))
 
1615
        return;
 
1616
    ASPrintf(&svr, "%s -help 2>&1", sa->str);
 
1617
    if (!(fp = popen(svr, "r")))
 
1618
        return;
 
1619
    buf[fread(buf, 1, sizeof(buf) - 1, fp)] = 0;
 
1620
    pclose(fp);
 
1621
    if (strstr(buf, "\n-br "))
 
1622
        addStr(&sa, "-br");
 
1623
    if (strstr(buf, "\n-novtswitch "))
 
1624
        addStr(&sa, "-novtswitch");
 
1625
    if (strstr(buf, "\n-quiet "))
 
1626
        addStr(&sa, "-quiet");
 
1627
    ce->value = joinArgs(sa);
 
1628
    ce->written = True;
1622
1629
}
1623
1630
 
1624
1631
#ifdef XDMCP
1625
1632
static void
1626
 
cp_keyfile( Entry *ce, Section *cs ATTR_UNUSED )
1627
 
{
1628
 
        if (!ce->active) /* there is only the Global one */
1629
 
                return;
1630
 
        if (old_confs)
1631
 
                linkFile( ce );
1632
 
        else
1633
 
                if (!copyFile( ce, 0600, 0 ))
1634
 
                        ce->active = False;
1635
 
}
1636
 
 
1637
 
static void
1638
 
mk_xaccess( Entry *ce, Section *cs ATTR_UNUSED )
1639
 
{
1640
 
        if (!ce->active) /* there is only the Global one */
1641
 
                writeFile( def_Xaccess, 0644, def_xaccess );
1642
 
        else if (old_confs)
1643
 
                linkFile( ce );
1644
 
        else
1645
 
                copyFile( ce, 0644, 0 ); /* don't handle error, it will disable Xdmcp automatically */
1646
 
}
1647
 
 
1648
 
static void
1649
 
mk_willing( Entry *ce, Section *cs ATTR_UNUSED )
1650
 
{
1651
 
        const char *fname;
1652
 
 
1653
 
        if (!ce->active) /* there is only the Global one */
1654
 
                goto dflt;
1655
 
        else {
1656
 
                if (!(fname = strchr( ce->value, '/' )))
1657
 
                        return; /* obviously in-line (or empty) */
1658
 
                if (old_scripts || inNewDir( fname ))
1659
 
                        doLinkFile( fname );
1660
 
                else {
1661
 
                  dflt:
1662
 
                        ce->value = KDMCONF "/Xwilling";
1663
 
                        ce->active = ce->written = True;
1664
 
                        writeFile( ce->value, 0755, def_willing );
1665
 
                }
1666
 
        }
 
1633
cp_keyfile(Entry *ce, Section *cs ATTR_UNUSED)
 
1634
{
 
1635
    if (!ce->active) /* there is only the Global one */
 
1636
        return;
 
1637
    if (old_confs)
 
1638
        linkFile(ce);
 
1639
    else
 
1640
        if (!copyFile(ce, 0600, 0))
 
1641
            ce->active = False;
 
1642
}
 
1643
 
 
1644
static void
 
1645
mk_xaccess(Entry *ce, Section *cs ATTR_UNUSED)
 
1646
{
 
1647
    if (!ce->active) /* there is only the Global one */
 
1648
        writeFile(def_Xaccess, 0644, def_xaccess);
 
1649
    else if (old_confs)
 
1650
        linkFile(ce);
 
1651
    else
 
1652
        copyFile(ce, 0644, 0); /* don't handle error, it will disable Xdmcp automatically */
 
1653
}
 
1654
 
 
1655
static void
 
1656
mk_willing(Entry *ce, Section *cs ATTR_UNUSED)
 
1657
{
 
1658
    const char *fname;
 
1659
 
 
1660
    if (!ce->active) { /* there is only the Global one */
 
1661
        goto dflt;
 
1662
    } else {
 
1663
        if (!(fname = strchr(ce->value, '/')))
 
1664
            return; /* obviously in-line (or empty) */
 
1665
        if (old_scripts || inNewDir(fname)) {
 
1666
            doLinkFile(fname);
 
1667
        } else {
 
1668
          dflt:
 
1669
            ce->value = KDMCONF "/Xwilling";
 
1670
            ce->active = ce->written = True;
 
1671
            writeFile(ce->value, 0755, def_willing);
 
1672
        }
 
1673
    }
1667
1674
}
1668
1675
#endif
1669
1676
 
1670
1677
/*
1671
1678
static int
1672
 
edit_resources( File *file )
 
1679
edit_resources(File *file)
1673
1680
{
1674
 
        // XXX remove any login*, chooser*, ... resources
1675
 
        return False;
 
1681
    // XXX remove any login*, chooser*, ... resources
 
1682
    return False;
1676
1683
}
1677
1684
*/
1678
1685
 
1679
1686
static void
1680
 
cp_resources( Entry *ce, Section *cs ATTR_UNUSED )
 
1687
cp_resources(Entry *ce, Section *cs ATTR_UNUSED)
1681
1688
{
1682
 
        if (!ce->active) /* the X-*-Greeter one */
1683
 
                return;
1684
 
        if (old_confs)
1685
 
                linkFile( ce );
1686
 
        else
1687
 
                if (!copyFile( ce, 0644, 0/*edit_resources*/ ))
1688
 
                        ce->active = False;
 
1689
    if (!ce->active) /* the X-*-Greeter one */
 
1690
        return;
 
1691
    if (old_confs)
 
1692
        linkFile(ce);
 
1693
    else
 
1694
        if (!copyFile(ce, 0644, 0/*edit_resources*/))
 
1695
            ce->active = False;
1689
1696
}
1690
1697
 
1691
1698
static int
1692
 
delstr( File *fil, const char *pat )
 
1699
delstr(File *fil, const char *pat)
1693
1700
{
1694
 
        char *p, *pp, *bpp;
1695
 
        const char *pap, *paap;
 
1701
    char *p, *pp, *bpp;
 
1702
    const char *pap, *paap;
1696
1703
 
1697
 
        *fil->eof = 0;
1698
 
        for (p = fil->buf; *p; p++) {
1699
 
                for (pp = p, pap = pat; ; ) {
1700
 
                        if (!*pap) {
1701
 
                                *p = '\n';
1702
 
                                memcpy( p + 1, pp, fil->eof - pp + 1 );
1703
 
                                fil->eof -= pp - p - 1;
1704
 
                                return True;
1705
 
                        } else if (!memcmp( pap, "*/", 2 )) {
1706
 
                                paap = pap += 2;
1707
 
                                while (!isspace( *pap ))
1708
 
                                        pap++;
1709
 
                                if (*pp != '/')
1710
 
                                        break;
1711
 
                                for (;;)
1712
 
                                        for (bpp = ++pp; *pp != '/'; pp++)
1713
 
                                                if (!*pp || isspace( *pp ))
1714
 
                                                        goto wbrk;
1715
 
                          wbrk:
1716
 
                                if ((pp - bpp != pap - paap) || memcmp( bpp, paap, pap - paap ))
1717
 
                                        break;
1718
 
                        } else if (*pap == '\t') {
1719
 
                                pap++;
1720
 
                                while (*pp == ' ' || *pp == '\t')
1721
 
                                        pp++;
1722
 
                        } else if (*pap == '[') {
1723
 
                                pap++;
1724
 
                                for (;;) {
1725
 
                                        if (!*pap) {
1726
 
                                                fprintf( stderr, "Internal error: unterminated char set\n" );
1727
 
                                                exit( 1 );
1728
 
                                        }
1729
 
                                        if (*pap == *pp) {
1730
 
                                                while (*++pap != ']')
1731
 
                                                        if (!*pap) {
1732
 
                                                                fprintf( stderr, "Internal error: unterminated char set\n" );
1733
 
                                                                exit( 1 );
1734
 
                                                        }
1735
 
                                                pap++;
1736
 
                                                pp++;
1737
 
                                                break;
1738
 
                                        }
1739
 
                                        if (*++pap == ']')
1740
 
                                                goto no;
1741
 
                                }
1742
 
                        } else {
1743
 
                                if (*pap == '\n')
1744
 
                                        while (*pp == ' ' || *pp == '\t')
1745
 
                                                pp++;
1746
 
                                if (*pap != *pp)
1747
 
                                        break;
1748
 
                                pap++;
1749
 
                                pp++;
1750
 
                        }
1751
 
                }
1752
 
          no: ;
1753
 
        }
1754
 
        return False;
 
1704
    *fil->eof = 0;
 
1705
    for (p = fil->buf; *p; p++) {
 
1706
        for (pp = p, pap = pat; ;) {
 
1707
            if (!*pap) {
 
1708
                *p = '\n';
 
1709
                memcpy(p + 1, pp, fil->eof - pp + 1);
 
1710
                fil->eof -= pp - p - 1;
 
1711
                return True;
 
1712
            } else if (!memcmp(pap, "*/", 2)) {
 
1713
                paap = pap += 2;
 
1714
                while (!isspace(*pap))
 
1715
                    pap++;
 
1716
                if (*pp != '/')
 
1717
                    break;
 
1718
                for (;;)
 
1719
                    for (bpp = ++pp; *pp != '/'; pp++)
 
1720
                        if (!*pp || isspace(*pp))
 
1721
                            goto wbrk;
 
1722
              wbrk:
 
1723
                if ((pp - bpp != pap - paap) || memcmp(bpp, paap, pap - paap))
 
1724
                    break;
 
1725
            } else if (*pap == '\t') {
 
1726
                pap++;
 
1727
                while (*pp == ' ' || *pp == '\t')
 
1728
                    pp++;
 
1729
            } else if (*pap == '[') {
 
1730
                pap++;
 
1731
                for (;;) {
 
1732
                    if (!*pap) {
 
1733
                        fprintf(stderr, "Internal error: unterminated char set\n");
 
1734
                        exit(1);
 
1735
                    }
 
1736
                    if (*pap == *pp) {
 
1737
                        while (*++pap != ']')
 
1738
                            if (!*pap) {
 
1739
                                fprintf(stderr, "Internal error: unterminated char set\n");
 
1740
                                exit(1);
 
1741
                            }
 
1742
                        pap++;
 
1743
                        pp++;
 
1744
                        break;
 
1745
                    }
 
1746
                    if (*++pap == ']')
 
1747
                        goto no;
 
1748
                }
 
1749
            } else {
 
1750
                if (*pap == '\n')
 
1751
                    while (*pp == ' ' || *pp == '\t')
 
1752
                        pp++;
 
1753
                if (*pap != *pp)
 
1754
                    break;
 
1755
                pap++;
 
1756
                pp++;
 
1757
            }
 
1758
        }
 
1759
      no: ;
 
1760
    }
 
1761
    return False;
1755
1762
}
1756
1763
 
1757
1764
/* XXX
1762
1769
static int mod_usebg;
1763
1770
 
1764
1771
static int
1765
 
edit_setup( File *file )
 
1772
edit_setup(File *file)
1766
1773
{
1767
 
        int chg =
1768
 
                delstr( file, "\n"
1769
 
                        "(\n"
1770
 
                        "  PIDFILE=/var/run/kdmdesktop-$DISPLAY.pid\n"
1771
 
                        "  */kdmdesktop\t&\n"
1772
 
                        "  echo $! >$PIDFILE\n"
1773
 
                        "  wait $!\n"
1774
 
                        "  rm $PIDFILE\n"
1775
 
                        ")\t&\n" ) |
1776
 
                delstr( file, "\n"
1777
 
                        "*/kdmdesktop\t&\n" ) |
1778
 
                delstr( file, "\n"
1779
 
                        "kdmdesktop\t&\n" ) |
1780
 
                delstr( file, "\n"
1781
 
                        "kdmdesktop\n" );
1782
 
        putVal( "UseBackground", chg ? "true" : "false" );
1783
 
        return chg;
 
1774
    int chg =
 
1775
        delstr(file, "\n"
 
1776
               "(\n"
 
1777
               "  PIDFILE=/var/run/kdmdesktop-$DISPLAY.pid\n"
 
1778
               "  */kdmdesktop\t&\n"
 
1779
               "  echo $! >$PIDFILE\n"
 
1780
               "  wait $!\n"
 
1781
               "  rm $PIDFILE\n"
 
1782
               ")\t&\n") |
 
1783
        delstr(file, "\n"
 
1784
               "*/kdmdesktop\t&\n") |
 
1785
        delstr(file, "\n"
 
1786
               "kdmdesktop\t&\n") |
 
1787
        delstr(file, "\n"
 
1788
               "kdmdesktop\n");
 
1789
    putVal("UseBackground", chg ? "true" : "false");
 
1790
    return chg;
1784
1791
}
1785
1792
 
1786
1793
static void
1787
 
mk_setup( Entry *ce, Section *cs )
 
1794
mk_setup(Entry *ce, Section *cs)
1788
1795
{
1789
 
        setSect( reSect( cs->name, "Greeter" ) );
1790
 
        if (old_scripts || mixed_scripts) {
1791
 
                if (mod_usebg && *ce->value)
1792
 
                        putVal( "UseBackground", "false" );
1793
 
                linkFile( ce );
1794
 
        } else {
1795
 
                if (ce->active && inNewDir( ce->value )) {
1796
 
                        if (mod_usebg)
1797
 
                                copyFile( ce, 0755, edit_setup );
1798
 
                        else
1799
 
                                linkFile( ce );
1800
 
                } else {
1801
 
                        ce->value = KDMCONF "/Xsetup";
1802
 
                        ce->active = ce->written = True;
1803
 
                        writeFile( ce->value, 0755, def_setup );
1804
 
                }
1805
 
        }
 
1796
    setSect(reSect(cs->name, "Greeter"));
 
1797
    if (old_scripts || mixed_scripts) {
 
1798
        if (mod_usebg && *ce->value)
 
1799
            putVal("UseBackground", "false");
 
1800
        linkFile(ce);
 
1801
    } else {
 
1802
        if (ce->active && inNewDir(ce->value)) {
 
1803
            if (mod_usebg)
 
1804
                copyFile(ce, 0755, edit_setup);
 
1805
            else
 
1806
                linkFile(ce);
 
1807
        } else {
 
1808
            ce->value = KDMCONF "/Xsetup";
 
1809
            ce->active = ce->written = True;
 
1810
            writeFile(ce->value, 0755, def_setup);
 
1811
        }
 
1812
    }
1806
1813
}
1807
1814
 
1808
1815
static int
1809
 
edit_startup( File *file )
 
1816
edit_startup(File *file)
1810
1817
{
1811
 
        int chg1 = False, chg2 = False;
 
1818
    int chg1 = False, chg2 = False;
1812
1819
 
1813
 
        if (mod_usebg &&
1814
 
            (delstr( file, "\n"
1815
 
                     "PIDFILE=/var/run/kdmdesktop-$DISPLAY.pid\n"
1816
 
                     "if [[] -f $PIDFILE ] ; then\n"
1817
 
                     "     kill `cat $PIDFILE`\n"
1818
 
                     "fi\n" ) ||
1819
 
             delstr( file, "\n"
1820
 
                     "PIDFILE=/var/run/kdmdesktop-$DISPLAY.pid\n"
1821
 
                     "test -f $PIDFILE && kill `cat $PIDFILE`\n" )))
1822
 
                chg1 = True;
1823
 
        if (oldver < 0x0203) {
1824
 
                chg2 =
 
1820
    if (mod_usebg &&
 
1821
        (delstr(file, "\n"
 
1822
                "PIDFILE=/var/run/kdmdesktop-$DISPLAY.pid\n"
 
1823
                "if [[] -f $PIDFILE ] ; then\n"
 
1824
                "          kill `cat $PIDFILE`\n"
 
1825
                "fi\n") ||
 
1826
         delstr(file, "\n"
 
1827
                "PIDFILE=/var/run/kdmdesktop-$DISPLAY.pid\n"
 
1828
                "test -f $PIDFILE && kill `cat $PIDFILE`\n")))
 
1829
        chg1 = True;
 
1830
    if (oldver < 0x0203) {
 
1831
        chg2 =
1825
1832
#ifdef _AIX
1826
 
                        delstr( file, "\n"
1827
 
"# We create a pseudodevice for finger.  (host:0 becomes [kx]dm/host_0)\n" );
 
1833
            delstr(file, "\n"
 
1834
"# We create a pseudodevice for finger.  (host:0 becomes [kx]dm/host_0)\n");
1828
1835
"# Without it, finger errors out with \"Cannot stat /dev/host:0\".\n"
1829
1836
"#\n"
1830
1837
"if [[] -f /usr/lib/X11/xdm/sessreg ]; then\n"
1849
1856
"fi\n") |
1850
1857
#else
1851
1858
# ifdef BSD
1852
 
                        delstr( file, "\n"
1853
 
"exec sessreg -a -l $DISPLAY -x */Xservers -u " _PATH_UTMP " $USER\n" ) |
 
1859
            delstr(file, "\n"
 
1860
"exec sessreg -a -l $DISPLAY -x */Xservers -u " _PATH_UTMP " $USER\n") |
1854
1861
# endif
1855
1862
#endif /* _AIX */
1856
 
                        delstr( file, "\n"
 
1863
            delstr(file, "\n"
1857
1864
"exec sessreg -a -l $DISPLAY"
1858
1865
#ifdef BSD
1859
1866
" -x */Xservers"
1860
1867
#endif
1861
 
" $USER\n" ) |
1862
 
                        delstr( file, "\n"
1863
 
"exec sessreg -a -l $DISPLAY -u /var/run/utmp -x */Xservers $USER\n" );
1864
 
                putVal( "UseSessReg", chg2 ? "true" : "false" );
1865
 
        }
1866
 
        return chg1 | chg2;
 
1868
" $USER\n") |
 
1869
            delstr(file, "\n"
 
1870
"exec sessreg -a -l $DISPLAY -u /var/run/utmp -x */Xservers $USER\n");
 
1871
        putVal("UseSessReg", chg2 ? "true" : "false");
 
1872
    }
 
1873
    return chg1 | chg2;
1867
1874
}
1868
1875
 
1869
1876
static void
1870
 
mk_startup( Entry *ce, Section *cs )
 
1877
mk_startup(Entry *ce, Section *cs)
1871
1878
{
1872
 
        setSect( cs->name );
1873
 
        if (old_scripts || mixed_scripts)
1874
 
                linkFile( ce );
1875
 
        else {
1876
 
                if (ce->active && inNewDir( ce->value )) {
1877
 
                        if (mod_usebg || oldver < 0x0203)
1878
 
                                copyFile( ce, 0755, edit_startup );
1879
 
                        else
1880
 
                                linkFile( ce );
1881
 
                } else {
1882
 
                        ce->value = KDMCONF "/Xstartup";
1883
 
                        ce->active = ce->written = True;
1884
 
                        writeFile( ce->value, 0755, def_startup );
1885
 
                }
1886
 
        }
 
1879
    setSect(cs->name);
 
1880
    if (old_scripts || mixed_scripts) {
 
1881
        linkFile(ce);
 
1882
    } else {
 
1883
        if (ce->active && inNewDir(ce->value)) {
 
1884
            if (mod_usebg || oldver < 0x0203)
 
1885
                copyFile(ce, 0755, edit_startup);
 
1886
            else
 
1887
                linkFile(ce);
 
1888
        } else {
 
1889
            ce->value = KDMCONF "/Xstartup";
 
1890
            ce->active = ce->written = True;
 
1891
            writeFile(ce->value, 0755, def_startup);
 
1892
        }
 
1893
    }
1887
1894
}
1888
1895
 
1889
1896
static int
1890
 
edit_reset( File *file )
 
1897
edit_reset(File *file)
1891
1898
{
1892
 
        return
 
1899
    return
1893
1900
#ifdef _AIX
1894
 
                delstr( file, "\n"
 
1901
        delstr(file, "\n"
1895
1902
"if [[] -f /usr/lib/X11/xdm/sessreg ]; then\n"
1896
1903
"  devname=`echo $DISPLAY | /usr/bin/sed -e 's/[[]:\\.]/_/g' | /usr/bin/cut -c1-8`\n"
1897
1904
"  exec /usr/lib/X11/xdm/sessreg -d -l [kx]dm/$devname $USER\n"
1898
 
"fi\n" ) |
 
1905
"fi\n") |
1899
1906
#else
1900
1907
# ifdef BSD
1901
 
                delstr( file, "\n"
1902
 
"exec sessreg -d -l $DISPLAY -x */Xservers -u " _PATH_UTMP " $USER\n" ) |
 
1908
        delstr(file, "\n"
 
1909
"exec sessreg -d -l $DISPLAY -x */Xservers -u " _PATH_UTMP " $USER\n") |
1903
1910
# endif
1904
1911
#endif /* _AIX */
1905
 
                delstr( file, "\n"
 
1912
        delstr(file, "\n"
1906
1913
"exec sessreg -d -l $DISPLAY"
1907
1914
# ifdef BSD
1908
1915
" -x */Xservers"
1909
1916
# endif
1910
 
" $USER\n" ) |
1911
 
                delstr( file, "\n"
1912
 
"exec sessreg -d -l $DISPLAY -u /var/run/utmp -x */Xservers $USER\n" );
1913
 
}
1914
 
 
1915
 
static void
1916
 
mk_reset( Entry *ce, Section *cs ATTR_UNUSED )
1917
 
{
1918
 
        if (old_scripts || mixed_scripts)
1919
 
                linkFile( ce );
1920
 
        else {
1921
 
                if (ce->active && inNewDir( ce->value )) {
1922
 
                        if (oldver < 0x0203)
1923
 
                                copyFile( ce, 0755, edit_reset );
1924
 
                        else
1925
 
                                linkFile( ce );
1926
 
                } else {
1927
 
                        ce->value = KDMCONF "/Xreset";
1928
 
                        ce->active = ce->written = True;
1929
 
                        writeFile( ce->value, 0755, def_reset );
1930
 
                }
1931
 
        }
1932
 
}
1933
 
 
1934
 
static void
1935
 
mk_session( Entry *ce, Section *cs ATTR_UNUSED )
1936
 
{
1937
 
        char *def_session;
1938
 
        const char *tmpf;
1939
 
 
1940
 
        if ((old_scripts || (ce->active && inNewDir( ce->value ))) &&
1941
 
            oldver >= 0x202)
1942
 
                linkFile( ce );
1943
 
        else {
1944
 
                tmpf = locate( "mktemp" ) ?
1945
 
                           "`mktemp /tmp/xsess-env-XXXXXX`" :
1946
 
                           locate( "tempfile" ) ?
1947
 
                               "`tempfile`" :
1948
 
                               "$HOME/.xsession-env-$DISPLAY";
1949
 
                ASPrintf( &def_session, "%s%s%s", def_session1, tmpf, def_session2 );
1950
 
                ce->value = KDMCONF "/Xsession";
1951
 
                ce->active = ce->written = True;
1952
 
                writeFile( ce->value, 0755, def_session );
1953
 
        }
1954
 
}
1955
 
 
1956
 
static void
1957
 
upd_language( Entry *ce, Section *cs ATTR_UNUSED )
1958
 
{
1959
 
        if (!strcmp( ce->value, "C" ))
1960
 
                ce->value = (char *)"en_US";
1961
 
}
1962
 
 
1963
 
static void
1964
 
upd_guistyle( Entry *ce, Section *cs ATTR_UNUSED )
1965
 
{
1966
 
        if (!strcmp( ce->value, "Motif+" ))
1967
 
                ce->value = (char *)"MotifPlus";
1968
 
        else if (!strcmp( ce->value, "KDE" ))
1969
 
                ce->value = (char *)"Default";
1970
 
}
1971
 
 
1972
 
static void
1973
 
upd_showusers( Entry *ce, Section *cs )
1974
 
{
1975
 
        if (!strcmp( ce->value, "All" ))
1976
 
                ce->value = (char *)"NotHidden";
1977
 
        else if (!strcmp( ce->value, "None" )) {
1978
 
                if (ce->active)
1979
 
                        putFqVal( cs->name, "UserList", "false" );
1980
 
                ce->value = (char *)"Selected";
1981
 
                ce->active = False;
1982
 
                ce->written = True;
1983
 
        }
 
1917
" $USER\n") |
 
1918
        delstr(file, "\n"
 
1919
"exec sessreg -d -l $DISPLAY -u /var/run/utmp -x */Xservers $USER\n");
 
1920
}
 
1921
 
 
1922
static void
 
1923
mk_reset(Entry *ce, Section *cs ATTR_UNUSED)
 
1924
{
 
1925
    if (old_scripts || mixed_scripts) {
 
1926
        linkFile(ce);
 
1927
    } else {
 
1928
        if (ce->active && inNewDir(ce->value)) {
 
1929
            if (oldver < 0x0203)
 
1930
                copyFile(ce, 0755, edit_reset);
 
1931
            else
 
1932
                linkFile(ce);
 
1933
        } else {
 
1934
            ce->value = KDMCONF "/Xreset";
 
1935
            ce->active = ce->written = True;
 
1936
            writeFile(ce->value, 0755, def_reset);
 
1937
        }
 
1938
    }
 
1939
}
 
1940
 
 
1941
static void
 
1942
mk_session(Entry *ce, Section *cs ATTR_UNUSED)
 
1943
{
 
1944
    char *def_session;
 
1945
    const char *tmpf;
 
1946
 
 
1947
    if ((old_scripts || (ce->active && inNewDir(ce->value))) &&
 
1948
            oldver >= 0x202) {
 
1949
        linkFile(ce);
 
1950
    } else {
 
1951
        tmpf = locate("mktemp") ?
 
1952
                   "`mktemp /tmp/xsess-env-XXXXXX`" :
 
1953
                   locate("tempfile") ?
 
1954
                       "`tempfile`" :
 
1955
                       "$HOME/.xsession-env-$DISPLAY";
 
1956
        ASPrintf(&def_session, "%s%s%s", def_session1, tmpf, def_session2);
 
1957
        ce->value = KDMCONF "/Xsession";
 
1958
        ce->active = ce->written = True;
 
1959
        writeFile(ce->value, 0755, def_session);
 
1960
    }
 
1961
}
 
1962
 
 
1963
static void
 
1964
upd_language(Entry *ce, Section *cs ATTR_UNUSED)
 
1965
{
 
1966
    if (!strcmp(ce->value, "C"))
 
1967
        ce->value = (char *)"en_US";
 
1968
}
 
1969
 
 
1970
static void
 
1971
upd_guistyle(Entry *ce, Section *cs ATTR_UNUSED)
 
1972
{
 
1973
    if (!strcmp(ce->value, "Motif+"))
 
1974
        ce->value = (char *)"MotifPlus";
 
1975
    else if (!strcmp(ce->value, "KDE"))
 
1976
        ce->value = (char *)"Default";
 
1977
}
 
1978
 
 
1979
static void
 
1980
upd_showusers(Entry *ce, Section *cs)
 
1981
{
 
1982
    if (!strcmp(ce->value, "All")) {
 
1983
        ce->value = (char *)"NotHidden";
 
1984
    } else if (!strcmp(ce->value, "None")) {
 
1985
        if (ce->active)
 
1986
            putFqVal(cs->name, "UserList", "false");
 
1987
        ce->value = (char *)"Selected";
 
1988
        ce->active = False;
 
1989
        ce->written = True;
 
1990
    }
1984
1991
}
1985
1992
 
1986
1993
static const char *defminuid, *defmaxuid;
1987
1994
 
1988
1995
static void
1989
 
upd_minshowuid( Entry *ce, Section *cs ATTR_UNUSED )
1990
 
{
1991
 
        if (!ce->active) {
1992
 
                ce->value = defminuid;
1993
 
                ce->active = ce->written = True;
1994
 
        }
1995
 
}
1996
 
 
1997
 
static void
1998
 
upd_maxshowuid( Entry *ce, Section *cs ATTR_UNUSED )
1999
 
{
2000
 
        if (!ce->active) {
2001
 
                ce->value = defmaxuid;
2002
 
                ce->active = ce->written = True;
2003
 
        }
2004
 
}
2005
 
 
2006
 
static void
2007
 
upd_hiddenusers( Entry *ce, Section *cs )
2008
 
{
2009
 
        char *nv;
2010
 
        const char *msu, *pt, *et;
2011
 
        struct passwd *pw;
2012
 
        unsigned minuid, maxuid;
2013
 
        char nbuf[128];
2014
 
 
2015
 
        if (!ce->active)
2016
 
                return;
2017
 
 
2018
 
        msu = getFqVal( cs->name, "MinShowUID", "0" );
2019
 
        sscanf( msu, "%u", &minuid );
2020
 
        msu = getFqVal( cs->name, "MaxShowUID", "65535" );
2021
 
        sscanf( msu, "%u", &maxuid );
2022
 
 
2023
 
        nv = 0;
2024
 
        pt = ce->value;
2025
 
        for (;;) {
2026
 
                et = strpbrk( pt, ";," );
2027
 
                if (et) {
2028
 
                        memcpy( nbuf, pt, et - pt );
2029
 
                        nbuf[et - pt] = 0;
2030
 
                } else
2031
 
                        strcpy( nbuf, pt );
2032
 
                if ((pw = getpwnam( nbuf ))) {
2033
 
                        if (!pw->pw_uid ||
2034
 
                            (pw->pw_uid >= minuid && pw->pw_uid <= maxuid))
2035
 
                        {
2036
 
                                if (nv)
2037
 
                                        strCat( &nv, ",%s", nbuf );
2038
 
                                else
2039
 
                                        nv = mstrdup( nbuf );
2040
 
                        }
2041
 
                }
2042
 
                if (!et)
2043
 
                        break;
2044
 
                pt = et + 1;
2045
 
        }
2046
 
        ce->value = nv ? nv : "";
2047
 
}
2048
 
 
2049
 
static void
2050
 
upd_forgingseed( Entry *ce, Section *cs ATTR_UNUSED )
2051
 
{
2052
 
        if (!ce->active) {
2053
 
                ASPrintf( (char **)&ce->value, "%d", time( 0 ) );
2054
 
                ce->active = ce->written = True;
2055
 
        }
2056
 
}
2057
 
 
2058
 
static void
2059
 
upd_fifodir( Entry *ce, Section *cs ATTR_UNUSED )
2060
 
{
2061
 
        const char *dir;
2062
 
        struct stat st;
2063
 
 
2064
 
        if (use_destdir)
2065
 
                return;
2066
 
        dir = ce->active ? ce->value : def_FifoDir;
2067
 
        stat( dir, &st );
2068
 
        chmod( dir, st.st_mode | 0755 );
 
1996
upd_minshowuid(Entry *ce, Section *cs ATTR_UNUSED)
 
1997
{
 
1998
    if (!ce->active) {
 
1999
        ce->value = defminuid;
 
2000
        ce->active = ce->written = True;
 
2001
    }
 
2002
}
 
2003
 
 
2004
static void
 
2005
upd_maxshowuid(Entry *ce, Section *cs ATTR_UNUSED)
 
2006
{
 
2007
    if (!ce->active) {
 
2008
        ce->value = defmaxuid;
 
2009
        ce->active = ce->written = True;
 
2010
    }
 
2011
}
 
2012
 
 
2013
static void
 
2014
upd_hiddenusers(Entry *ce, Section *cs)
 
2015
{
 
2016
    char *nv;
 
2017
    const char *msu, *pt, *et;
 
2018
    struct passwd *pw;
 
2019
    unsigned minuid, maxuid;
 
2020
    char nbuf[128];
 
2021
 
 
2022
    if (!ce->active)
 
2023
        return;
 
2024
 
 
2025
    msu = getFqVal(cs->name, "MinShowUID", "0");
 
2026
    sscanf(msu, "%u", &minuid);
 
2027
    msu = getFqVal(cs->name, "MaxShowUID", "65535");
 
2028
    sscanf(msu, "%u", &maxuid);
 
2029
 
 
2030
    nv = 0;
 
2031
    pt = ce->value;
 
2032
    for (;;) {
 
2033
        et = strpbrk(pt, ";,");
 
2034
        if (et) {
 
2035
            memcpy(nbuf, pt, et - pt);
 
2036
            nbuf[et - pt] = 0;
 
2037
        } else {
 
2038
            strcpy(nbuf, pt);
 
2039
        }
 
2040
        if ((pw = getpwnam(nbuf))) {
 
2041
            if (!pw->pw_uid ||
 
2042
                (pw->pw_uid >= minuid && pw->pw_uid <= maxuid))
 
2043
            {
 
2044
                if (nv)
 
2045
                    strCat(&nv, ",%s", nbuf);
 
2046
                else
 
2047
                    nv = mstrdup(nbuf);
 
2048
            }
 
2049
        }
 
2050
        if (!et)
 
2051
            break;
 
2052
        pt = et + 1;
 
2053
    }
 
2054
    ce->value = nv ? nv : "";
 
2055
}
 
2056
 
 
2057
static void
 
2058
upd_forgingseed(Entry *ce, Section *cs ATTR_UNUSED)
 
2059
{
 
2060
    if (!ce->active) {
 
2061
        ASPrintf((char **)&ce->value, "%d", time(0));
 
2062
        ce->active = ce->written = True;
 
2063
    }
 
2064
}
 
2065
 
 
2066
static void
 
2067
upd_fifodir(Entry *ce, Section *cs ATTR_UNUSED)
 
2068
{
 
2069
    const char *dir;
 
2070
    struct stat st;
 
2071
 
 
2072
    if (use_destdir)
 
2073
        return;
 
2074
    dir = ce->active ? ce->value : def_FifoDir;
 
2075
    stat(dir, &st);
 
2076
    chmod(dir, st.st_mode | 0755);
2069
2077
}
2070
2078
 
2071
2079
static gid_t greeter_gid;
2072
2080
static uid_t greeter_uid;
2073
2081
 
2074
2082
static void
2075
 
upd_greeteruid( Entry *ce, Section *cs ATTR_UNUSED )
2076
 
{
2077
 
        struct passwd *pw;
2078
 
        char *ok, *adduser;
2079
 
        int uid;
2080
 
 
2081
 
        if (use_destdir || !ce->active)
2082
 
                return;
2083
 
        if (!(pw = getpwnam( ce->value ))) {
2084
 
                uid = strtol( ce->value, &ok, 10 );
2085
 
                if (*ok || !(pw = getpwuid( uid ))) {
2086
 
                        if (!access( "/etc/debian_version", R_OK )
2087
 
                            && (adduser = locate( "adduser" ))) {
2088
 
                                const char *args[] = {
2089
 
                                        adduser, "--system", "--group",
2090
 
                                        "--home", "/var", "--no-create-home",
2091
 
                                        ce->value, 0
2092
 
                                };
2093
 
                                if (runAndWait( (char **)args )) {
2094
 
                                        fprintf( stderr, "Warning: Creation of missing GreeterUID"
2095
 
                                                         " user %s failed\n", ce->value );
2096
 
                                        ce->active = False;
2097
 
                                        return;
2098
 
                                }
2099
 
                        } else {
2100
 
                                fprintf( stderr, "Warning: Do not know how to create missing"
2101
 
                                                 " GreeterUID user %s\n", ce->value );
2102
 
                                ce->active = False;
2103
 
                                return;
2104
 
                        }
2105
 
                        if (!(pw = getpwnam( ce->value ))) {
2106
 
                                fprintf( stderr, "Warning: Newly created GreeterUID user %s"
2107
 
                                                 " still missing!?\n", ce->value );
2108
 
                                ce->active = False;
2109
 
                                return;
2110
 
                        }
2111
 
                }
2112
 
        }
2113
 
        greeter_uid = pw->pw_uid;
2114
 
        greeter_gid = pw->pw_gid;
2115
 
}
2116
 
 
2117
 
static void
2118
 
upd_datadir( Entry *ce, Section *cs ATTR_UNUSED )
2119
 
{
2120
 
        char *oldsts, *newsts;
2121
 
        const char *dir;
2122
 
        struct stat st;
2123
 
 
2124
 
        if (use_destdir)
2125
 
                return;
2126
 
        dir = ce->active ? ce->value : def_DataDir;
2127
 
        ASPrintf( &newsts, "%s/kdmsts", dir );
2128
 
        if (mkdirp( dir, 0755, "data", 0 ) && oldkde) {
2129
 
                ASPrintf( &oldsts, "%s/kdm/kdmsts", oldkde );
2130
 
                rename( oldsts, newsts );
2131
 
        }
2132
 
        if (stat( dir, &st ))
2133
 
                return;
2134
 
        if ((st.st_uid != greeter_uid || st.st_gid != greeter_gid) &&
2135
 
            chown( dir, greeter_uid, greeter_gid ))
2136
 
                fprintf( stderr, "Warning: Cannot assign ownership of data directory"
2137
 
                                 " %s: %s\n", dir, strerror( errno ) );
2138
 
        if (stat( newsts, &st ))
2139
 
                return;
2140
 
        if ((st.st_uid != greeter_uid || st.st_gid != greeter_gid) &&
2141
 
            chown( newsts, greeter_uid, greeter_gid ))
2142
 
                fprintf( stderr, "Warning: Cannot assign ownership of status file"
2143
 
                                 " %s: %s\n", newsts, strerror( errno ) );
2144
 
}
2145
 
 
2146
 
static void
2147
 
upd_userlogfile( Entry *ce, Section *cs ATTR_UNUSED )
2148
 
{
2149
 
        char *p;
2150
 
 
2151
 
        if ((p = strstr( ce->value, "%s" )))
2152
 
                ASPrintf( (char **)&ce->value, "%.*s%%d%s", p - ce->value, ce->value, p + 2 );
 
2083
upd_greeteruid(Entry *ce, Section *cs ATTR_UNUSED)
 
2084
{
 
2085
    struct passwd *pw;
 
2086
    char *ok, *adduser;
 
2087
    int uid;
 
2088
 
 
2089
    if (use_destdir || !ce->active)
 
2090
        return;
 
2091
    if (!(pw = getpwnam(ce->value))) {
 
2092
        uid = strtol(ce->value, &ok, 10);
 
2093
        if (*ok || !(pw = getpwuid(uid))) {
 
2094
            if (!access("/etc/debian_version", R_OK)
 
2095
                && (adduser = locate("adduser"))) {
 
2096
                const char *args[] = {
 
2097
                    adduser, "--system", "--group",
 
2098
                    "--home", "/var", "--no-create-home",
 
2099
                    ce->value, 0
 
2100
                };
 
2101
                if (runAndWait((char **)args)) {
 
2102
                    fprintf(stderr, "Warning: Creation of missing GreeterUID"
 
2103
                                    " user %s failed\n", ce->value);
 
2104
                    ce->active = False;
 
2105
                    return;
 
2106
                }
 
2107
            } else {
 
2108
                fprintf(stderr, "Warning: Do not know how to create missing"
 
2109
                                " GreeterUID user %s\n", ce->value);
 
2110
                ce->active = False;
 
2111
                return;
 
2112
            }
 
2113
            if (!(pw = getpwnam(ce->value))) {
 
2114
                fprintf(stderr, "Warning: Newly created GreeterUID user %s"
 
2115
                                " still missing!?\n", ce->value);
 
2116
                ce->active = False;
 
2117
                return;
 
2118
            }
 
2119
        }
 
2120
    }
 
2121
    greeter_uid = pw->pw_uid;
 
2122
    greeter_gid = pw->pw_gid;
 
2123
}
 
2124
 
 
2125
static void
 
2126
upd_datadir(Entry *ce, Section *cs ATTR_UNUSED)
 
2127
{
 
2128
    char *oldsts, *newsts;
 
2129
    const char *dir;
 
2130
    struct stat st;
 
2131
 
 
2132
    if (use_destdir)
 
2133
        return;
 
2134
    dir = ce->active ? ce->value : def_DataDir;
 
2135
    ASPrintf(&newsts, "%s/kdmsts", dir);
 
2136
    if (mkdirp(dir, 0755, "data", 0) && oldkde) {
 
2137
        ASPrintf(&oldsts, "%s/kdm/kdmsts", oldkde);
 
2138
        rename(oldsts, newsts);
 
2139
    }
 
2140
    if (stat(dir, &st))
 
2141
        return;
 
2142
    if ((st.st_uid != greeter_uid || st.st_gid != greeter_gid) &&
 
2143
            chown(dir, greeter_uid, greeter_gid))
 
2144
        fprintf(stderr, "Warning: Cannot assign ownership of data directory"
 
2145
                        " %s: %s\n", dir, strerror(errno));
 
2146
    if (stat(newsts, &st))
 
2147
        return;
 
2148
    if ((st.st_uid != greeter_uid || st.st_gid != greeter_gid) &&
 
2149
            chown(newsts, greeter_uid, greeter_gid))
 
2150
        fprintf(stderr, "Warning: Cannot assign ownership of status file"
 
2151
                        " %s: %s\n", newsts, strerror(errno));
 
2152
}
 
2153
 
 
2154
static void
 
2155
upd_userlogfile(Entry *ce, Section *cs ATTR_UNUSED)
 
2156
{
 
2157
    char *p;
 
2158
 
 
2159
    if ((p = strstr(ce->value, "%s")))
 
2160
        ASPrintf((char **)&ce->value, "%.*s%%d%s", p - ce->value, ce->value, p + 2);
2153
2161
}
2154
2162
 
2155
2163
/*
2158
2166
 * Do not complain if source cannot be read.
2159
2167
 */
2160
2168
static void
2161
 
copyPlainFile( const char *from, const char *to )
 
2169
copyPlainFile(const char *from, const char *to)
2162
2170
{
2163
 
        File file;
2164
 
        int fd;
 
2171
    File file;
 
2172
    int fd;
2165
2173
 
2166
 
        if (readFile( &file, from )) {
2167
 
                if ((fd = open( to, O_WRONLY | O_CREAT | O_EXCL, 0644 )) >= 0) {
2168
 
                        size_t len = file.eof - file.buf;
2169
 
                        if (write( fd, file.buf, len ) != (ssize_t)len) {
2170
 
                                fprintf( stderr, "Warning: cannot write %s (disk full?)\n", to );
2171
 
                                unlink( to );
2172
 
                        }
2173
 
                        if (close( fd ) < 0) {
2174
 
                                fprintf( stderr, "Warning: cannot write %s (disk full?)\n", to );
2175
 
                                unlink( to );
2176
 
                        }
2177
 
                } else if (errno != EEXIST)
2178
 
                        fprintf( stderr, "Warning: cannot create %s\n", to );
2179
 
                freeBuf( &file );
2180
 
        }
 
2174
    if (readFile(&file, from)) {
 
2175
        if ((fd = open(to, O_WRONLY | O_CREAT | O_EXCL, 0644)) >= 0) {
 
2176
            size_t len = file.eof - file.buf;
 
2177
            if (write(fd, file.buf, len) != (ssize_t)len) {
 
2178
                fprintf(stderr, "Warning: cannot write %s (disk full?)\n", to);
 
2179
                unlink(to);
 
2180
            }
 
2181
            if (close(fd) < 0) {
 
2182
                fprintf(stderr, "Warning: cannot write %s (disk full?)\n", to);
 
2183
                unlink(to);
 
2184
            }
 
2185
        } else if (errno != EEXIST) {
 
2186
            fprintf(stderr, "Warning: cannot create %s\n", to);
 
2187
        }
 
2188
        freeBuf(&file);
 
2189
    }
2181
2190
}
2182
2191
 
2183
2192
static int
2184
 
copyDir( const char *from, const char *to )
2185
 
{
2186
 
        DIR *dir;
2187
 
        struct dirent *ent;
2188
 
        struct stat st;
2189
 
        char bn[PATH_MAX], bo[PATH_MAX];
2190
 
 
2191
 
        if (!(dir = opendir( from )))
2192
 
                return False;
2193
 
        while ((ent = readdir( dir ))) {
2194
 
                if (!strcmp( ent->d_name, "." ) || !strcmp( ent->d_name, ".." ))
2195
 
                        continue;
2196
 
                sprintf( bo, "%s/%s", from, ent->d_name );
2197
 
                if (stat( bo, &st ) || !S_ISREG( st.st_mode ))
2198
 
                        continue;
2199
 
                sprintf( bn, "%s/%s", to, ent->d_name );
2200
 
                copyPlainFile( bo, bn );
2201
 
        }
2202
 
        closedir( dir );
2203
 
        return True;
2204
 
}
2205
 
 
2206
 
static void
2207
 
upd_facedir( Entry *ce, Section *cs ATTR_UNUSED )
2208
 
{
2209
 
        char *oldpic, *newpic, *olddir;
2210
 
        struct passwd *pw;
2211
 
 
2212
 
        if (use_destdir)
2213
 
                return;
2214
 
        if (oldkdepfx) { /* Do we have a previous install? */
2215
 
                /* This would be the prev install's default location */
2216
 
                ASPrintf( &olddir, "%s/share/apps/kdm/faces", oldkdepfx );
2217
 
                if (ce->active && strcmp( olddir, ce->value ))
2218
 
                        /* Not default location, so don't touch the setting. */
2219
 
                        return;
2220
 
                /* Default location, so absorb it. */
2221
 
                ce->active = False;
2222
 
                /* Don't copy if old dir == new new. */
2223
 
                if (!strcmp( olddir, def_FaceDir ))
2224
 
                        olddir = 0;
2225
 
        } else
2226
 
                olddir = 0;
2227
 
        if (mkdirp( def_FaceDir, 0755, "user face", True )) {
2228
 
                const char *defpic = def_FaceDir "/.default.face.icon";
2229
 
                const char *rootpic = def_FaceDir "/root.face.icon";
2230
 
                if (oldkde && (!olddir || !copyDir( olddir, def_FaceDir )) &&
2231
 
                    oldver < 0x0201) /* This isn't exact - didn't inc version. */
2232
 
                {
2233
 
                        setpwent();
2234
 
                        while ((pw = getpwent()))
2235
 
                                if (strcmp( pw->pw_name, "root" )) {
2236
 
                                        ASPrintf( &oldpic, "%s/share/apps/kdm/pics/users/%s.png",
2237
 
                                                  oldkdepfx, pw->pw_name );
2238
 
                                        ASPrintf( &newpic, def_FaceDir "/%s.face.icon", pw->pw_name );
2239
 
                                        rename( oldpic, newpic );
2240
 
                                        free( newpic );
2241
 
                                        free( oldpic );
2242
 
                                }
2243
 
                        endpwent();
2244
 
                        ASPrintf( &oldpic, "%s/share/apps/kdm/pics/users/default.png", oldkdepfx );
2245
 
                        if (!rename( oldpic, defpic ))
2246
 
                                defpic = 0;
2247
 
                        ASPrintf( &oldpic, "%s/share/apps/kdm/pics/users/root.png", oldkdepfx );
2248
 
                        if (!rename( oldpic, rootpic ))
2249
 
                                rootpic = 0;
2250
 
                }
2251
 
                if (defpic) {
2252
 
                        ASPrintf( &oldpic, "%s/default1.png", facesrc );
2253
 
                        copyPlainFile( oldpic, defpic );
2254
 
                }
2255
 
                if (rootpic) {
2256
 
                        ASPrintf( &oldpic, "%s/root1.png", facesrc );
2257
 
                        copyPlainFile( oldpic, rootpic );
2258
 
                }
2259
 
        }
2260
 
}
2261
 
 
2262
 
static void
2263
 
upd_sessionsdirs( Entry *ce, Section *cs ATTR_UNUSED )
2264
 
{
2265
 
        StrList *sl, *sp;
2266
 
        int olen;
2267
 
        char olddir[PATH_MAX];
2268
 
 
2269
 
        if (ce->written) {
2270
 
                sprintf( olddir, "%s/share/apps/kdm/sessions", oldkdepfx );
2271
 
                olen = strlen( oldkde );
2272
 
                sl = splitList( ce->value );
2273
 
                for (sp = sl; sp; sp = sp->next) {
2274
 
                        if (!strcmp( sp->str, olddir ))
2275
 
                                sp->str = def_SessionsDirs;
2276
 
                        else if (!memcmp( sp->str, oldkde, olen ) &&
2277
 
                                 !memcmp( sp->str + olen, "/kdm/", 5 ))
2278
 
                        {
2279
 
                                char nd[PATH_MAX];
2280
 
                                sprintf( nd, "%s%s", newdir, sp->str + olen + 4 );
2281
 
                                mkdirp( nd, 0755, "sessions", False );
2282
 
                                copyDir( sp->str, nd );
2283
 
                                ASPrintf( (char **)&sp->str, KDMCONF "%s", sp->str + olen + 4 );
2284
 
                        }
2285
 
                }
2286
 
                ce->value = joinList( sl );
2287
 
        } else {
2288
 
                char nd[PATH_MAX];
2289
 
                sprintf( nd, "%s/sessions", newdir );
2290
 
                mkdirp( nd, 0755, "sessions", False );
2291
 
        }
2292
 
}
2293
 
 
2294
 
static void
2295
 
upd_preloader( Entry *ce, Section *cs ATTR_UNUSED )
2296
 
{
2297
 
        if (ce->written) { /* implies oldkde != 0 */
2298
 
                char *oldpl;
2299
 
                ASPrintf( &oldpl, "%s/bin/preloadkde", oldkdepfx );
2300
 
                if (!strcmp( ce->value, oldpl ))
2301
 
                        ce->value = (char *)KDE_BINDIR "/preloadkde";
2302
 
                free( oldpl );
2303
 
        }
 
2193
copyDir(const char *from, const char *to)
 
2194
{
 
2195
    DIR *dir;
 
2196
    struct dirent *ent;
 
2197
    struct stat st;
 
2198
    char bn[PATH_MAX], bo[PATH_MAX];
 
2199
 
 
2200
    if (!(dir = opendir(from)))
 
2201
        return False;
 
2202
    while ((ent = readdir(dir))) {
 
2203
        if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
 
2204
            continue;
 
2205
        sprintf(bo, "%s/%s", from, ent->d_name);
 
2206
        if (stat(bo, &st) || !S_ISREG(st.st_mode))
 
2207
            continue;
 
2208
        sprintf(bn, "%s/%s", to, ent->d_name);
 
2209
        copyPlainFile(bo, bn);
 
2210
    }
 
2211
    closedir(dir);
 
2212
    return True;
 
2213
}
 
2214
 
 
2215
static void
 
2216
upd_facedir(Entry *ce, Section *cs ATTR_UNUSED)
 
2217
{
 
2218
    char *oldpic, *newpic, *olddir;
 
2219
    struct passwd *pw;
 
2220
 
 
2221
    if (use_destdir)
 
2222
        return;
 
2223
    if (oldkdepfx) { /* Do we have a previous install? */
 
2224
        /* This would be the prev install's default location */
 
2225
        ASPrintf(&olddir, "%s/share/apps/kdm/faces", oldkdepfx);
 
2226
        if (ce->active && strcmp(olddir, ce->value))
 
2227
            /* Not default location, so don't touch the setting. */
 
2228
            return;
 
2229
        /* Default location, so absorb it. */
 
2230
        ce->active = False;
 
2231
        /* Don't copy if old dir == new new. */
 
2232
        if (!strcmp(olddir, def_FaceDir))
 
2233
            olddir = 0;
 
2234
    } else {
 
2235
        olddir = 0;
 
2236
    }
 
2237
    if (mkdirp(def_FaceDir, 0755, "user face", True)) {
 
2238
        const char *defpic = def_FaceDir "/.default.face.icon";
 
2239
        const char *rootpic = def_FaceDir "/root.face.icon";
 
2240
        if (oldkde && (!olddir || !copyDir(olddir, def_FaceDir)) &&
 
2241
            oldver < 0x0201) /* This isn't exact - didn't inc version. */
 
2242
        {
 
2243
            setpwent();
 
2244
            while ((pw = getpwent()))
 
2245
                if (strcmp(pw->pw_name, "root")) {
 
2246
                    ASPrintf(&oldpic, "%s/share/apps/kdm/pics/users/%s.png",
 
2247
                             oldkdepfx, pw->pw_name);
 
2248
                    ASPrintf(&newpic, def_FaceDir "/%s.face.icon", pw->pw_name);
 
2249
                    rename(oldpic, newpic);
 
2250
                    free(newpic);
 
2251
                    free(oldpic);
 
2252
                }
 
2253
            endpwent();
 
2254
            ASPrintf(&oldpic, "%s/share/apps/kdm/pics/users/default.png", oldkdepfx);
 
2255
            if (!rename(oldpic, defpic))
 
2256
                defpic = 0;
 
2257
            ASPrintf(&oldpic, "%s/share/apps/kdm/pics/users/root.png", oldkdepfx);
 
2258
            if (!rename(oldpic, rootpic))
 
2259
                rootpic = 0;
 
2260
        }
 
2261
        if (defpic) {
 
2262
            ASPrintf(&oldpic, "%s/default1.png", facesrc);
 
2263
            copyPlainFile(oldpic, defpic);
 
2264
        }
 
2265
        if (rootpic) {
 
2266
            ASPrintf(&oldpic, "%s/root1.png", facesrc);
 
2267
            copyPlainFile(oldpic, rootpic);
 
2268
        }
 
2269
    }
 
2270
}
 
2271
 
 
2272
static void
 
2273
upd_sessionsdirs(Entry *ce, Section *cs ATTR_UNUSED)
 
2274
{
 
2275
    StrList *sl, *sp;
 
2276
    int olen;
 
2277
    char olddir[PATH_MAX];
 
2278
 
 
2279
    if (ce->written) {
 
2280
        sprintf(olddir, "%s/share/apps/kdm/sessions", oldkdepfx);
 
2281
        olen = strlen(oldkde);
 
2282
        sl = splitList(ce->value);
 
2283
        for (sp = sl; sp; sp = sp->next) {
 
2284
            if (!strcmp(sp->str, olddir)) {
 
2285
                sp->str = def_SessionsDirs;
 
2286
            } else if (!memcmp(sp->str, oldkde, olen) &&
 
2287
                       !memcmp(sp->str + olen, "/kdm/", 5)) {
 
2288
                char nd[PATH_MAX];
 
2289
                sprintf(nd, "%s%s", newdir, sp->str + olen + 4);
 
2290
                mkdirp(nd, 0755, "sessions", False);
 
2291
                copyDir(sp->str, nd);
 
2292
                ASPrintf((char **)&sp->str, KDMCONF "%s", sp->str + olen + 4);
 
2293
            }
 
2294
        }
 
2295
        ce->value = joinList(sl);
 
2296
    } else {
 
2297
        char nd[PATH_MAX];
 
2298
        sprintf(nd, "%s/sessions", newdir);
 
2299
        mkdirp(nd, 0755, "sessions", False);
 
2300
    }
 
2301
}
 
2302
 
 
2303
static void
 
2304
upd_preloader(Entry *ce, Section *cs ATTR_UNUSED)
 
2305
{
 
2306
    if (ce->written) { /* implies oldkde != 0 */
 
2307
        char *oldpl;
 
2308
        ASPrintf(&oldpl, "%s/bin/preloadkde", oldkdepfx);
 
2309
        if (!strcmp(ce->value, oldpl))
 
2310
            ce->value = (char *)KDE_BINDIR "/preloadkde";
 
2311
        free(oldpl);
 
2312
    }
2304
2313
}
2305
2314
 
2306
2315
 
2307
2316
CONF_GEN_ENTRIES
2308
2317
 
2309
2318
static Sect *
2310
 
findSect( const char *name )
 
2319
findSect(const char *name)
2311
2320
{
2312
 
        const char *p;
2313
 
        int i;
 
2321
    const char *p;
 
2322
    int i;
2314
2323
 
2315
 
        p = strrchr( name, '-' );
2316
 
        if (!p)
2317
 
                p = name;
2318
 
        for (i = 0; i < as(allSects); i++)
2319
 
                if (!strcmp( allSects[i]->name, p ))
2320
 
                        return allSects[i];
2321
 
        fprintf( stderr, "Internal error: unknown section %s\n", name );
2322
 
        exit( 1 );
 
2324
    p = strrchr(name, '-');
 
2325
    if (!p)
 
2326
        p = name;
 
2327
    for (i = 0; i < as(allSects); i++)
 
2328
        if (!strcmp(allSects[i]->name, p))
 
2329
            return allSects[i];
 
2330
    fprintf(stderr, "Internal error: unknown section %s\n", name);
 
2331
    exit(1);
2323
2332
}
2324
2333
 
2325
2334
static Ent *
2326
 
findEnt( Sect *sect, const char *key )
 
2335
findEnt(Sect *sect, const char *key)
2327
2336
{
2328
 
        int i;
 
2337
    int i;
2329
2338
 
2330
 
        for (i = 0; i < sect->nents; i++)
2331
 
                if (!strcmp( sect->ents[i].key, key ))
2332
 
                        return sect->ents + i;
2333
 
        fprintf( stderr, "Internal error: unknown key %s in section %s\n",
2334
 
                 key, sect->name );
2335
 
        exit( 1 );
 
2339
    for (i = 0; i < sect->nents; i++)
 
2340
        if (!strcmp(sect->ents[i].key, key))
 
2341
            return sect->ents + i;
 
2342
    fprintf(stderr, "Internal error: unknown key %s in section %s\n",
 
2343
            key, sect->name);
 
2344
    exit(1);
2336
2345
}
2337
2346
 
2338
2347
 
2341
2350
 */
2342
2351
 
2343
2352
typedef struct DEnt {
2344
 
        const char *key;
2345
 
        const char *value;
2346
 
        int active;
 
2353
    const char *key;
 
2354
    const char *value;
 
2355
    int active;
2347
2356
} DEnt;
2348
2357
 
2349
2358
typedef struct DSect {
2350
 
        const char *name;
2351
 
        DEnt *ents;
2352
 
        int nents;
2353
 
        const char *comment;
 
2359
    const char *name;
 
2360
    DEnt *ents;
 
2361
    int nents;
 
2362
    const char *comment;
2354
2363
} DSect;
2355
2364
 
2356
2365
CONF_GEN_EXAMPLE
2357
2366
 
2358
2367
static void
2359
 
makeDefaultConfig( void )
 
2368
makeDefaultConfig(void)
2360
2369
{
2361
 
        Section *cs, **csp;
2362
 
        Entry *ce, **cep;
2363
 
        int sc, ec;
 
2370
    Section *cs, **csp;
 
2371
    Entry *ce, **cep;
 
2372
    int sc, ec;
2364
2373
 
2365
 
        for (csp = &config, sc = 0; sc < as(dAllSects); csp = &(cs->next), sc++) {
2366
 
                cs = mcalloc( sizeof(*cs) );
2367
 
                *csp = cs;
2368
 
                cs->spec = findSect( dAllSects[sc].name );
2369
 
                cs->name = dAllSects[sc].name;
2370
 
                cs->comment = dAllSects[sc].comment;
2371
 
                for (cep = &(cs->ents), ec = 0; ec < dAllSects[sc].nents;
2372
 
                     cep = &(ce->next), ec++)
2373
 
                {
2374
 
                        ce = mcalloc( sizeof(*ce) );
2375
 
                        *cep = ce;
2376
 
                        ce->spec = findEnt( cs->spec, dAllSects[sc].ents[ec].key );
2377
 
                        ce->value = dAllSects[sc].ents[ec].value;
2378
 
                        ce->active = dAllSects[sc].ents[ec].active;
2379
 
                }
2380
 
        }
 
2374
    for (csp = &config, sc = 0; sc < as(dAllSects); csp = &(cs->next), sc++) {
 
2375
        cs = mcalloc(sizeof(*cs));
 
2376
        *csp = cs;
 
2377
        cs->spec = findSect(dAllSects[sc].name);
 
2378
        cs->name = dAllSects[sc].name;
 
2379
        cs->comment = dAllSects[sc].comment;
 
2380
        for (cep = &(cs->ents), ec = 0; ec < dAllSects[sc].nents;
 
2381
             cep = &(ce->next), ec++)
 
2382
        {
 
2383
            ce = mcalloc(sizeof(*ce));
 
2384
            *cep = ce;
 
2385
            ce->spec = findEnt(cs->spec, dAllSects[sc].ents[ec].key);
 
2386
            ce->value = dAllSects[sc].ents[ec].value;
 
2387
            ce->active = dAllSects[sc].ents[ec].active;
 
2388
        }
 
2389
    }
2381
2390
}
2382
2391
 
2383
2392
 
2386
2395
 */
2387
2396
 
2388
2397
typedef struct REntry {
2389
 
        struct REntry *next;
2390
 
        const char *key;
2391
 
        char *value;
 
2398
    struct REntry *next;
 
2399
    const char *key;
 
2400
    char *value;
2392
2401
} REntry;
2393
2402
 
2394
2403
typedef struct RSection {
2395
 
        struct RSection *next;
2396
 
        const char *name;
2397
 
        REntry *ents;
 
2404
    struct RSection *next;
 
2405
    const char *name;
 
2406
    REntry *ents;
2398
2407
} RSection;
2399
2408
 
2400
2409
static RSection *
2401
 
readConfig( const char *fname )
 
2410
readConfig(const char *fname)
2402
2411
{
2403
 
        char *nstr;
2404
 
        char *s, *e, *st, *en, *ek, *sl;
2405
 
        RSection *rootsec = 0, *cursec;
2406
 
        REntry *curent;
2407
 
        int nlen;
2408
 
        int line, sectmoan;
2409
 
        File file;
2410
 
 
2411
 
        if (!readFile( &file, fname ))
2412
 
                return 0;
2413
 
        usedFile( fname );
2414
 
 
2415
 
        for (s = file.buf, line = 0, cursec = 0, sectmoan = 1; s < file.eof; s++) {
2416
 
                line++;
2417
 
 
2418
 
                while ((s < file.eof) && isspace( *s ) && (*s != '\n'))
2419
 
                        s++;
2420
 
 
2421
 
                if ((s < file.eof) && ((*s == '\n') || (*s == '#'))) {
2422
 
                  sktoeol:
2423
 
                        while ((s < file.eof) && (*s != '\n'))
2424
 
                                s++;
2425
 
                        continue;
2426
 
                }
2427
 
                sl = s;
2428
 
 
2429
 
                if (*s == '[') {
2430
 
                        while ((s < file.eof) && (*s != '\n'))
2431
 
                                s++;
2432
 
                        e = s - 1;
2433
 
                        while ((e > sl) && isspace( *e ))
2434
 
                                e--;
2435
 
                        if (*e != ']') {
2436
 
                                fprintf( stderr, "Invalid section header at %s:%d\n",
2437
 
                                         fname, line );
2438
 
                                continue;
2439
 
                        }
2440
 
                        sectmoan = False;
2441
 
                        nstr = sl + 1;
2442
 
                        nlen = e - nstr;
2443
 
                        for (cursec = rootsec; cursec; cursec = cursec->next)
2444
 
                                if (!memcmp( nstr, cursec->name, nlen ) &&
2445
 
                                    !cursec->name[nlen])
2446
 
                                {
 
2412
    char *nstr;
 
2413
    char *s, *e, *st, *en, *ek, *sl;
 
2414
    RSection *rootsec = 0, *cursec;
 
2415
    REntry *curent;
 
2416
    int nlen;
 
2417
    int line, sectmoan;
 
2418
    File file;
 
2419
 
 
2420
    if (!readFile(&file, fname))
 
2421
        return 0;
 
2422
    usedFile(fname);
 
2423
 
 
2424
    for (s = file.buf, line = 0, cursec = 0, sectmoan = 1; s < file.eof; s++) {
 
2425
        line++;
 
2426
 
 
2427
        while ((s < file.eof) && isspace(*s) && (*s != '\n'))
 
2428
            s++;
 
2429
 
 
2430
        if ((s < file.eof) && ((*s == '\n') || (*s == '#'))) {
 
2431
          sktoeol:
 
2432
            while ((s < file.eof) && (*s != '\n'))
 
2433
                s++;
 
2434
            continue;
 
2435
        }
 
2436
        sl = s;
 
2437
 
 
2438
        if (*s == '[') {
 
2439
            while ((s < file.eof) && (*s != '\n'))
 
2440
                s++;
 
2441
            e = s - 1;
 
2442
            while ((e > sl) && isspace(*e))
 
2443
                e--;
 
2444
            if (*e != ']') {
 
2445
                fprintf(stderr, "Invalid section header at %s:%d\n",
 
2446
                        fname, line);
 
2447
                continue;
 
2448
            }
 
2449
            sectmoan = False;
 
2450
            nstr = sl + 1;
 
2451
            nlen = e - nstr;
 
2452
            for (cursec = rootsec; cursec; cursec = cursec->next)
 
2453
                if (!memcmp(nstr, cursec->name, nlen) &&
 
2454
                    !cursec->name[nlen])
 
2455
                {
2447
2456
#if 0 /* not our business ... */
2448
 
                                        fprintf( stderr, "Warning: Multiple occurrences of section "
2449
 
                                                 "[%.*s] in %s. Consider merging them.\n",
2450
 
                                                 nlen, nstr, fname );
 
2457
                    fprintf(stderr, "Warning: Multiple occurrences of section "
 
2458
                            "[%.*s] in %s. Consider merging them.\n",
 
2459
                            nlen, nstr, fname);
2451
2460
#endif
2452
 
                                        goto secfnd;
2453
 
                                }
2454
 
                        cursec = mmalloc( sizeof(*cursec) );
2455
 
                        ASPrintf( (char **)&cursec->name, "%.*s", nlen, nstr );
2456
 
                        cursec->ents = 0;
2457
 
                        cursec->next = rootsec;
2458
 
                        rootsec = cursec;
2459
 
                  secfnd:
2460
 
                        continue;
2461
 
                }
2462
 
 
2463
 
                if (!cursec) {
2464
 
                        if (sectmoan) {
2465
 
                                sectmoan = False;
2466
 
                                fprintf( stderr, "Entry outside any section at %s:%d",
2467
 
                                         fname, line );
2468
 
                        }
2469
 
                        goto sktoeol;
2470
 
                }
2471
 
 
2472
 
                for (; (s < file.eof) && (*s != '\n'); s++)
2473
 
                        if (*s == '=')
2474
 
                                goto haveeq;
2475
 
                fprintf( stderr, "Invalid entry (missing '=') at %s:%d\n", fname, line );
2476
 
                continue;
2477
 
 
2478
 
          haveeq:
2479
 
                for (ek = s - 1;; ek--) {
2480
 
                        if (ek < sl) {
2481
 
                                fprintf( stderr, "Invalid entry (empty key) at %s:%d\n",
2482
 
                                         fname, line );
2483
 
                                goto sktoeol;
2484
 
                        }
2485
 
                        if (!isspace( *ek ))
2486
 
                                break;
2487
 
                }
2488
 
 
2489
 
                s++;
2490
 
                while ((s < file.eof) && isspace( *s ) && (*s != '\n'))
2491
 
                        s++;
2492
 
                st = s;
2493
 
                while ((s < file.eof) && (*s != '\n'))
2494
 
                        s++;
2495
 
                for (en = s - 1; en >= st && isspace( *en ); en--);
2496
 
 
2497
 
                nstr = sl;
2498
 
                nlen = ek - sl + 1;
2499
 
                for (curent = cursec->ents; curent; curent = curent->next)
2500
 
                        if (!memcmp( nstr, curent->key, nlen ) &&
2501
 
                            !curent->key[nlen]) {
2502
 
                                fprintf( stderr, "Multiple occurrences of key '%s' in section "
2503
 
                                         "[%s] of %s.\n", curent->key, cursec->name, fname );
2504
 
                                goto keyfnd;
2505
 
                        }
2506
 
                curent = mmalloc( sizeof(*curent) );
2507
 
                ASPrintf( (char **)&curent->key, "%.*s", nlen, nstr );
2508
 
                ASPrintf( (char **)&curent->value, "%.*s", en - st + 1, st );
2509
 
                curent->next = cursec->ents;
2510
 
                cursec->ents = curent;
2511
 
          keyfnd:
2512
 
                continue;
2513
 
        }
2514
 
        return rootsec;
 
2461
                    goto secfnd;
 
2462
                }
 
2463
            cursec = mmalloc(sizeof(*cursec));
 
2464
            ASPrintf((char **)&cursec->name, "%.*s", nlen, nstr);
 
2465
            cursec->ents = 0;
 
2466
            cursec->next = rootsec;
 
2467
            rootsec = cursec;
 
2468
          secfnd:
 
2469
            continue;
 
2470
        }
 
2471
 
 
2472
        if (!cursec) {
 
2473
            if (sectmoan) {
 
2474
                sectmoan = False;
 
2475
                fprintf(stderr, "Entry outside any section at %s:%d",
 
2476
                        fname, line);
 
2477
            }
 
2478
            goto sktoeol;
 
2479
        }
 
2480
 
 
2481
        for (; (s < file.eof) && (*s != '\n'); s++)
 
2482
            if (*s == '=')
 
2483
                goto haveeq;
 
2484
        fprintf(stderr, "Invalid entry (missing '=') at %s:%d\n", fname, line);
 
2485
        continue;
 
2486
 
 
2487
      haveeq:
 
2488
        for (ek = s - 1;; ek--) {
 
2489
            if (ek < sl) {
 
2490
                fprintf(stderr, "Invalid entry (empty key) at %s:%d\n",
 
2491
                        fname, line);
 
2492
                goto sktoeol;
 
2493
            }
 
2494
            if (!isspace(*ek))
 
2495
                break;
 
2496
        }
 
2497
 
 
2498
        s++;
 
2499
        while ((s < file.eof) && isspace(*s) && (*s != '\n'))
 
2500
            s++;
 
2501
        st = s;
 
2502
        while ((s < file.eof) && (*s != '\n'))
 
2503
            s++;
 
2504
        for (en = s - 1; en >= st && isspace(*en); en--);
 
2505
 
 
2506
        nstr = sl;
 
2507
        nlen = ek - sl + 1;
 
2508
        for (curent = cursec->ents; curent; curent = curent->next)
 
2509
            if (!memcmp(nstr, curent->key, nlen) && !curent->key[nlen]) {
 
2510
                fprintf(stderr, "Multiple occurrences of key '%s' in section "
 
2511
                        "[%s] of %s.\n", curent->key, cursec->name, fname);
 
2512
                goto keyfnd;
 
2513
            }
 
2514
        curent = mmalloc(sizeof(*curent));
 
2515
        ASPrintf((char **)&curent->key, "%.*s", nlen, nstr);
 
2516
        ASPrintf((char **)&curent->value, "%.*s", en - st + 1, st);
 
2517
        curent->next = cursec->ents;
 
2518
        cursec->ents = curent;
 
2519
      keyfnd:
 
2520
        continue;
 
2521
    }
 
2522
    return rootsec;
2515
2523
}
2516
2524
 
2517
2525
 
2518
2526
static int
2519
 
mergeKdmRcOld( const char *path )
 
2527
mergeKdmRcOld(const char *path)
2520
2528
{
2521
 
        char *p;
2522
 
        struct stat st;
 
2529
    char *p;
 
2530
    struct stat st;
2523
2531
 
2524
 
        ASPrintf( &p, "%s/kdmrc", path );
2525
 
        if (stat( p, &st )) {
2526
 
                free( p );
2527
 
                return False;
2528
 
        }
2529
 
        printf( "Information: ignoring pre-existing kdmrc %s from kde < 2.2\n", p );
2530
 
        free( p );
2531
 
        return True;
 
2532
    ASPrintf(&p, "%s/kdmrc", path);
 
2533
    if (stat(p, &st)) {
 
2534
        free(p);
 
2535
        return False;
 
2536
    }
 
2537
    printf("Information: ignoring pre-existing kdmrc %s from kde < 2.2\n", p);
 
2538
    free(p);
 
2539
    return True;
2532
2540
}
2533
2541
 
2534
2542
typedef struct {
2535
 
        const char *sect, *key, *def;
2536
 
        int (*cond)( void );
 
2543
    const char *sect, *key, *def;
 
2544
    int (*cond)(void);
2537
2545
} FDefs;
2538
2546
 
2539
2547
/*
2542
2550
 * defaults were used so far.
2543
2551
 */
2544
2552
static void
2545
 
applyDefs( FDefs *chgdef, int ndefs, const char *path )
 
2553
applyDefs(FDefs *chgdef, int ndefs, const char *path)
2546
2554
{
2547
 
        char *p;
2548
 
        int i;
 
2555
    char *p;
 
2556
    int i;
2549
2557
 
2550
 
        for (i = 0; i < ndefs; i++)
2551
 
                if (!getFqVal( chgdef[i].sect, chgdef[i].key, 0 ) &&
2552
 
                    (!chgdef[i].cond || chgdef[i].cond()))
2553
 
                {
2554
 
                        ASPrintf( &p, chgdef[i].def, path );
2555
 
                        putFqVal( chgdef[i].sect, chgdef[i].key, p );
2556
 
                        free( p );
2557
 
                }
 
2558
    for (i = 0; i < ndefs; i++)
 
2559
        if (!getFqVal(chgdef[i].sect, chgdef[i].key, 0) &&
 
2560
            (!chgdef[i].cond || chgdef[i].cond()))
 
2561
        {
 
2562
            ASPrintf(&p, chgdef[i].def, path);
 
2563
            putFqVal(chgdef[i].sect, chgdef[i].key, p);
 
2564
            free(p);
 
2565
        }
2558
2566
}
2559
2567
 
2560
2568
static int
2561
2569
if_usebg (void)
2562
2570
{
2563
 
        return isTrue( getFqVal( "X-*-Greeter", "UseBackground", "true" ) );
 
2571
    return isTrue(getFqVal("X-*-Greeter", "UseBackground", "true"));
2564
2572
}
2565
2573
 
2566
2574
static FDefs kdmdefs_all[] = {
2576
2584
};
2577
2585
 
2578
2586
typedef struct KUpdEnt {
2579
 
        const char *okey, *nsec, *nkey;
2580
 
        void (*func)( const char *sect, char **value );
 
2587
    const char *okey, *nsec, *nkey;
 
2588
    void (*func)(const char *sect, char **value);
2581
2589
} KUpdEnt;
2582
2590
 
2583
2591
typedef struct KUpdSec {
2584
 
        const char *osec;
2585
 
        KUpdEnt *ents;
2586
 
        int nents;
 
2592
    const char *osec;
 
2593
    KUpdEnt *ents;
 
2594
    int nents;
2587
2595
} KUpdSec;
2588
2596
 
2589
2597
#ifdef XDMCP
2590
2598
static void
2591
 
P_EnableChooser( const char *sect ATTR_UNUSED, char **value )
 
2599
P_EnableChooser(const char *sect ATTR_UNUSED, char **value)
2592
2600
{
2593
 
        *value = (char *)(isTrue( *value ) ? "DefaultLocal" : "LocalOnly");
 
2601
    *value = (char *)(isTrue(*value) ? "DefaultLocal" : "LocalOnly");
2594
2602
}
2595
2603
#endif
2596
2604
 
2597
2605
static void
2598
 
P_UseLilo( const char *sect ATTR_UNUSED, char **value )
 
2606
P_UseLilo(const char *sect ATTR_UNUSED, char **value)
2599
2607
{
2600
 
        *value = (char *)(isTrue( *value ) ? "Lilo" : "None");
 
2608
    *value = (char *)(isTrue(*value) ? "Lilo" : "None");
2601
2609
}
2602
2610
 
2603
2611
static void
2604
 
P_EchoMode( const char *sect ATTR_UNUSED, char **value )
 
2612
P_EchoMode(const char *sect ATTR_UNUSED, char **value)
2605
2613
{
2606
 
        *value = (char *)(!strcmp( *value, "NoEcho" ) ? "false" : "true");
 
2614
    *value = (char *)(!strcmp(*value, "NoEcho") ? "false" : "true");
2607
2615
}
2608
2616
 
2609
2617
CONF_GEN_KMERGE
2610
2618
 
2611
2619
static int
2612
 
mergeKdmRcNewer( const char *path, int obsRet )
 
2620
mergeKdmRcNewer(const char *path, int obsRet)
2613
2621
{
2614
 
        char *p;
2615
 
        const char *cp, *sec, *key;
2616
 
        RSection *rootsect, *cs;
2617
 
        REntry *ce;
2618
 
        int i, j, ma, mi;
2619
 
        static char sname[64];
 
2622
    char *p;
 
2623
    const char *cp, *sec, *key;
 
2624
    RSection *rootsect, *cs;
 
2625
    REntry *ce;
 
2626
    int i, j, ma, mi;
 
2627
    static char sname[64];
2620
2628
 
2621
 
        ASPrintf( &p, "%s/kdm/kdmrc", path );
2622
 
        if (!(rootsect = readConfig( p ))) {
2623
 
                free( p );
2624
 
                return False;
2625
 
        }
2626
 
        for (cs = rootsect; cs; cs = cs->next)
2627
 
                if (!strcmp( cs->name, "General" ))
2628
 
                        for (ce = cs->ents; ce; ce = ce->next)
2629
 
                                if (!strcmp( ce->key, "ConfigVersion" ))
2630
 
                                        goto gotcfgv;
2631
 
        printf( "Information: ignoring pre-existing kdmrc %s from kde < 3.1\n", p );
2632
 
        free( p );
2633
 
        return obsRet;
 
2629
    ASPrintf(&p, "%s/kdm/kdmrc", path);
 
2630
    if (!(rootsect = readConfig(p))) {
 
2631
        free(p);
 
2632
        return False;
 
2633
    }
 
2634
    for (cs = rootsect; cs; cs = cs->next)
 
2635
        if (!strcmp(cs->name, "General"))
 
2636
            for (ce = cs->ents; ce; ce = ce->next)
 
2637
                if (!strcmp(ce->key, "ConfigVersion"))
 
2638
                    goto gotcfgv;
 
2639
    printf("Information: ignoring pre-existing kdmrc %s from kde < 3.1\n", p);
 
2640
    free(p);
 
2641
    return obsRet;
2634
2642
  gotcfgv:
2635
 
        sscanf( ce->value, "%d.%d", &ma, &mi );
2636
 
        oldver = (ma << 8) | mi;
2637
 
        printf( "Information: reading pre-existing kdmrc %s (config version %d.%d)\n",
2638
 
                p, ma, mi );
2639
 
        free( p );
2640
 
 
2641
 
        for (cs = rootsect; cs; cs = cs->next) {
2642
 
                        cp = strrchr( cs->name, '-' );
2643
 
                        if (!cp)
2644
 
                                cp = cs->name;
2645
 
                        else if (cs->name[0] != 'X' || cs->name[1] != '-')
2646
 
                                goto dropsec;
2647
 
                        for (i = 0; i < as(kupsects); i++)
2648
 
                                if (!strcmp( cp, kupsects[i].osec )) {
2649
 
                                        for (ce = cs->ents; ce; ce = ce->next) {
2650
 
                                                for (j = 0; j < kupsects[i].nents; j++)
2651
 
                                                        if (!strcmp( ce->key, kupsects[i].ents[j].okey )) {
2652
 
                                                                if (kupsects[i].ents[j].nsec == (char *)-1) {
2653
 
                                                                        kupsects[i].ents[j].func( 0, &ce->value );
2654
 
                                                                        goto gotkey;
2655
 
                                                                }
2656
 
                                                                if (!kupsects[i].ents[j].nsec)
2657
 
                                                                        sec = cs->name;
2658
 
                                                                else {
2659
 
                                                                        sec = sname;
2660
 
                                                                        sprintf( sname, "%.*s-%s",
2661
 
                                                                                 (int)(cp - cs->name), cs->name,
2662
 
                                                                                 kupsects[i].ents[j].nsec );
2663
 
                                                                }
2664
 
                                                                if (!kupsects[i].ents[j].nkey)
2665
 
                                                                        key = ce->key;
2666
 
                                                                else
2667
 
                                                                        key = kupsects[i].ents[j].nkey;
2668
 
                                                                if (kupsects[i].ents[j].func)
2669
 
                                                                        kupsects[i].ents[j].func( sec, &ce->value );
2670
 
                                                                putFqVal( sec, key, ce->value );
2671
 
                                                                goto gotkey;
2672
 
                                                        }
2673
 
                                                printf( "Information: dropping key %s from section [%s]\n",
2674
 
                                                        ce->key, cs->name );
2675
 
                                          gotkey: ;
2676
 
                                        }
2677
 
                                        goto gotsec;
2678
 
                                }
2679
 
                  dropsec:
2680
 
                        printf( "Information: dropping section [%s]\n", cs->name );
2681
 
                  gotsec: ;
2682
 
        }
2683
 
 
2684
 
        applyDefs( kdmdefs_all, as(kdmdefs_all), path );
2685
 
 
2686
 
        return True;
 
2643
    sscanf(ce->value, "%d.%d", &ma, &mi);
 
2644
    oldver = (ma << 8) | mi;
 
2645
    printf("Information: reading pre-existing kdmrc %s (config version %d.%d)\n",
 
2646
           p, ma, mi);
 
2647
    free(p);
 
2648
 
 
2649
    for (cs = rootsect; cs; cs = cs->next) {
 
2650
        cp = strrchr(cs->name, '-');
 
2651
        if (!cp)
 
2652
            cp = cs->name;
 
2653
        else if (cs->name[0] != 'X' || cs->name[1] != '-')
 
2654
            goto dropsec;
 
2655
        for (i = 0; i < as(kupsects); i++)
 
2656
            if (!strcmp(cp, kupsects[i].osec)) {
 
2657
                for (ce = cs->ents; ce; ce = ce->next) {
 
2658
                    for (j = 0; j < kupsects[i].nents; j++)
 
2659
                        if (!strcmp(ce->key, kupsects[i].ents[j].okey)) {
 
2660
                            if (kupsects[i].ents[j].nsec == (char *) - 1) {
 
2661
                                kupsects[i].ents[j].func(0, &ce->value);
 
2662
                                goto gotkey;
 
2663
                            }
 
2664
                            if (!kupsects[i].ents[j].nsec) {
 
2665
                                sec = cs->name;
 
2666
                            } else {
 
2667
                                sec = sname;
 
2668
                                sprintf(sname, "%.*s-%s",
 
2669
                                        (int)(cp - cs->name), cs->name,
 
2670
                                        kupsects[i].ents[j].nsec);
 
2671
                            }
 
2672
                            if (!kupsects[i].ents[j].nkey)
 
2673
                                key = ce->key;
 
2674
                            else
 
2675
                                key = kupsects[i].ents[j].nkey;
 
2676
                            if (kupsects[i].ents[j].func)
 
2677
                                kupsects[i].ents[j].func(sec, &ce->value);
 
2678
                            putFqVal(sec, key, ce->value);
 
2679
                            goto gotkey;
 
2680
                        }
 
2681
                    printf("Information: dropping key %s from section [%s]\n",
 
2682
                           ce->key, cs->name);
 
2683
                  gotkey:
 
2684
                    ;
 
2685
                }
 
2686
                goto gotsec;
 
2687
            }
 
2688
      dropsec:
 
2689
        printf("Information: dropping section [%s]\n", cs->name);
 
2690
      gotsec:
 
2691
        ;
 
2692
    }
 
2693
 
 
2694
    applyDefs(kdmdefs_all, as(kdmdefs_all), path);
 
2695
 
 
2696
    return True;
2687
2697
}
2688
2698
 
2689
2699
 
2690
2700
typedef struct XResEnt {
2691
 
        const char *xname;
2692
 
        const char *ksec, *kname;
2693
 
        void (*func)( const char *sect, char **value );
 
2701
    const char *xname;
 
2702
    const char *ksec, *kname;
 
2703
    void (*func)(const char *sect, char **value);
2694
2704
} XResEnt;
2695
2705
 
2696
2706
static void
2697
 
handleXdmVal( const char *dpy, const char *key, char *value,
2698
 
              const XResEnt *ents, int nents )
2699
 
{
2700
 
        const char *kname;
2701
 
        int i;
2702
 
        char knameb[80], sname[80];
2703
 
 
2704
 
        for (i = 0; i < nents; i++)
2705
 
                if (!strcmp( key, ents[i].xname ) ||
2706
 
                    (key[0] == toupper( ents[i].xname[0] ) &&
2707
 
                     !strcmp( key + 1, ents[i].xname + 1 )))
2708
 
                {
2709
 
                        if (ents[i].ksec == (char *)-1) {
2710
 
                                ents[i].func( 0, &value );
2711
 
                                break;
2712
 
                        }
2713
 
                        sprintf( sname, ents[i].ksec, dpy );
2714
 
                        if (ents[i].kname)
2715
 
                                kname = ents[i].kname;
2716
 
                        else {
2717
 
                                kname = knameb;
2718
 
                                sprintf( knameb, "%c%s",
2719
 
                                         toupper( ents[i].xname[0] ), ents[i].xname + 1 );
2720
 
                        }
2721
 
                        if (ents[i].func)
2722
 
                                ents[i].func( sname, &value );
2723
 
                        putFqVal( sname, kname, value );
2724
 
                        break;
2725
 
                }
2726
 
}
2727
 
 
2728
 
static void
2729
 
P_list( const char *sect ATTR_UNUSED, char **value )
2730
 
{
2731
 
        int is, d, s;
2732
 
        char *st;
2733
 
 
2734
 
        for (st = *value, is = False, d = s = 0; st[s]; s++)
2735
 
                if (st[s] == ' ' || st[s] == '\t') {
2736
 
                        if (!is)
2737
 
                                st[d++] = ',';
2738
 
                        is = True;
2739
 
                } else {
2740
 
                        st[d++] = st[s];
2741
 
                        is = False;
2742
 
                }
2743
 
        st[d] = 0;
2744
 
}
2745
 
 
2746
 
static void
2747
 
P_authDir( const char *sect ATTR_UNUSED, char **value )
2748
 
{
2749
 
        int l;
2750
 
 
2751
 
        l = strlen( *value );
2752
 
        if (l < 4) {
2753
 
                *value = 0;
2754
 
                return;
2755
 
        }
2756
 
        if ((*value)[l-1] == '/')
2757
 
                (*value)[--l] = 0;
2758
 
        if (!strncmp( *value, "/tmp/", 5 ) ||
2759
 
            !strncmp( *value, "/var/tmp/", 9 ))
2760
 
        {
2761
 
                printf( "Warning: Resetting inappropriate value %s for AuthDir to default\n",
2762
 
                        *value );
2763
 
                *value = 0;
2764
 
                return;
2765
 
        }
2766
 
        if ((l >= 4 && !strcmp( *value + l - 4, "/tmp" )) ||
2767
 
            (l >= 6 && !strcmp( *value + l - 6, "/xauth" )) ||
2768
 
            (l >= 8 && !strcmp( *value + l - 8, "/authdir" )) ||
2769
 
            (l >= 10 && !strcmp( *value + l - 10, "/authfiles" )))
2770
 
                return;
2771
 
        ASPrintf( value, "%s/authdir", *value );
2772
 
}
2773
 
 
2774
 
static void
2775
 
P_openDelay( const char *sect, char **value )
2776
 
{
2777
 
        putFqVal( sect, "ServerTimeout", *value );
2778
 
}
2779
 
 
2780
 
static void
2781
 
P_noPassUsers( const char *sect, char **value ATTR_UNUSED )
2782
 
{
2783
 
        putFqVal( sect, "NoPassEnable", "true" );
2784
 
}
2785
 
 
2786
 
static void
2787
 
P_autoUser( const char *sect, char **value ATTR_UNUSED )
2788
 
{
2789
 
        putFqVal( sect, "AutoLoginEnable", "true" );
 
2707
handleXdmVal(const char *dpy, const char *key, char *value,
 
2708
             const XResEnt *ents, int nents)
 
2709
{
 
2710
    const char *kname;
 
2711
    int i;
 
2712
    char knameb[80], sname[80];
 
2713
 
 
2714
    for (i = 0; i < nents; i++)
 
2715
        if (!strcmp(key, ents[i].xname) ||
 
2716
            (key[0] == toupper(ents[i].xname[0]) &&
 
2717
             !strcmp(key + 1, ents[i].xname + 1)))
 
2718
        {
 
2719
            if (ents[i].ksec == (char *)-1) {
 
2720
                ents[i].func(0, &value);
 
2721
                break;
 
2722
            }
 
2723
            sprintf(sname, ents[i].ksec, dpy);
 
2724
            if (ents[i].kname) {
 
2725
                kname = ents[i].kname;
 
2726
            } else {
 
2727
                kname = knameb;
 
2728
                sprintf(knameb, "%c%s",
 
2729
                        toupper(ents[i].xname[0]), ents[i].xname + 1);
 
2730
            }
 
2731
            if (ents[i].func)
 
2732
                ents[i].func(sname, &value);
 
2733
            putFqVal(sname, kname, value);
 
2734
            break;
 
2735
        }
 
2736
}
 
2737
 
 
2738
static void
 
2739
P_list(const char *sect ATTR_UNUSED, char **value)
 
2740
{
 
2741
    int is, d, s;
 
2742
    char *st;
 
2743
 
 
2744
    for (st = *value, is = False, d = s = 0; st[s]; s++)
 
2745
        if (st[s] == ' ' || st[s] == '\t') {
 
2746
            if (!is)
 
2747
                st[d++] = ',';
 
2748
            is = True;
 
2749
        } else {
 
2750
            st[d++] = st[s];
 
2751
            is = False;
 
2752
        }
 
2753
    st[d] = 0;
 
2754
}
 
2755
 
 
2756
static void
 
2757
P_authDir(const char *sect ATTR_UNUSED, char **value)
 
2758
{
 
2759
    int l;
 
2760
 
 
2761
    l = strlen(*value);
 
2762
    if (l < 4) {
 
2763
        *value = 0;
 
2764
        return;
 
2765
    }
 
2766
    if ((*value)[l-1] == '/')
 
2767
        (*value)[--l] = 0;
 
2768
    if (!strncmp(*value, "/tmp/", 5) ||
 
2769
        !strncmp(*value, "/var/tmp/", 9))
 
2770
    {
 
2771
        printf("Warning: Resetting inappropriate value %s for AuthDir to default\n",
 
2772
               *value);
 
2773
        *value = 0;
 
2774
        return;
 
2775
    }
 
2776
    if ((l >= 4 && !strcmp(*value + l - 4, "/tmp")) ||
 
2777
        (l >= 6 && !strcmp(*value + l - 6, "/xauth")) ||
 
2778
        (l >= 8 && !strcmp(*value + l - 8, "/authdir")) ||
 
2779
        (l >= 10 && !strcmp(*value + l - 10, "/authfiles")))
 
2780
        return;
 
2781
    ASPrintf(value, "%s/authdir", *value);
 
2782
}
 
2783
 
 
2784
static void
 
2785
P_openDelay(const char *sect, char **value)
 
2786
{
 
2787
    putFqVal(sect, "ServerTimeout", *value);
 
2788
}
 
2789
 
 
2790
static void
 
2791
P_noPassUsers(const char *sect, char **value ATTR_UNUSED)
 
2792
{
 
2793
    putFqVal(sect, "NoPassEnable", "true");
 
2794
}
 
2795
 
 
2796
static void
 
2797
P_autoUser(const char *sect, char **value ATTR_UNUSED)
 
2798
{
 
2799
    putFqVal(sect, "AutoLoginEnable", "true");
2790
2800
}
2791
2801
 
2792
2802
#ifdef XDMCP
2793
2803
static void
2794
 
P_requestPort( const char *sect, char **value )
 
2804
P_requestPort(const char *sect, char **value)
2795
2805
{
2796
 
        if (!strcmp( *value, "0" )) {
2797
 
                *value = 0;
2798
 
                putFqVal( sect, "Enable", "false" );
2799
 
        } else
2800
 
                putFqVal( sect, "Enable", "true" );
 
2806
    if (!strcmp(*value, "0")) {
 
2807
        *value = 0;
 
2808
        putFqVal(sect, "Enable", "false");
 
2809
    } else {
 
2810
        putFqVal(sect, "Enable", "true");
 
2811
    }
2801
2812
}
2802
2813
#endif
2803
2814
 
2804
2815
static int kdmrcmode = 0644;
2805
2816
 
2806
2817
static void
2807
 
P_autoPass( const char *sect ATTR_UNUSED, char **value ATTR_UNUSED )
 
2818
P_autoPass(const char *sect ATTR_UNUSED, char **value ATTR_UNUSED)
2808
2819
{
2809
 
        kdmrcmode = 0600;
 
2820
    kdmrcmode = 0600;
2810
2821
}
2811
2822
 
2812
2823
CONF_GEN_XMERGE
2814
2825
static XrmQuark XrmQString, empty = NULLQUARK;
2815
2826
 
2816
2827
static Bool
2817
 
dumpEntry( XrmDatabase *db ATTR_UNUSED,
2818
 
           XrmBindingList bindings,
2819
 
           XrmQuarkList quarks,
2820
 
           XrmRepresentation *type,
2821
 
           XrmValuePtr value,
2822
 
           XPointer data ATTR_UNUSED )
 
2828
dumpEntry(XrmDatabase *db ATTR_UNUSED,
 
2829
          XrmBindingList bindings,
 
2830
          XrmQuarkList quarks,
 
2831
          XrmRepresentation *type,
 
2832
          XrmValuePtr value,
 
2833
          XPointer data ATTR_UNUSED)
2823
2834
{
2824
 
        const char *dpy, *key;
2825
 
        int el, hasu;
2826
 
        char dpybuf[80];
 
2835
    const char *dpy, *key;
 
2836
    int el, hasu;
 
2837
    char dpybuf[80];
2827
2838
 
2828
 
        if (*type != XrmQString)
2829
 
                return False;
2830
 
        if (*bindings == XrmBindLoosely ||
2831
 
            strcmp( XrmQuarkToString (*quarks), "DisplayManager" ))
2832
 
                return False;
2833
 
        bindings++, quarks++;
2834
 
        if (!*quarks)
2835
 
                return False;
2836
 
        if (*bindings != XrmBindLoosely && !quarks[1]) { /* DM.foo */
2837
 
                key = XrmQuarkToString (*quarks);
2838
 
                handleXdmVal( 0, key, value->addr, globents, as(globents) );
2839
 
                return False;
2840
 
        } else if (*bindings == XrmBindLoosely && !quarks[1]) { /* DM*bar */
2841
 
                dpy = "*";
2842
 
                key = XrmQuarkToString (*quarks);
2843
 
        } else if (*bindings != XrmBindLoosely && quarks[1] &&
2844
 
                   *bindings != XrmBindLoosely && !quarks[2])
2845
 
        { /* DM.foo.bar */
2846
 
                dpy = dpybuf + 4;
2847
 
                strcpy( dpybuf + 4, XrmQuarkToString (*quarks) );
2848
 
                for (hasu = False, el = 4; dpybuf[el]; el++)
2849
 
                        if (dpybuf[el] == '_')
2850
 
                                hasu = True;
2851
 
                if (!hasu/* && isupper (dpy[0])*/) {
2852
 
                        dpy = dpybuf;
2853
 
                        memcpy( dpybuf, "*:*_", 4 );
2854
 
                } else {
2855
 
                        for (; --el >= 0; )
2856
 
                                if (dpybuf[el] == '_') {
2857
 
                                        dpybuf[el] = ':';
2858
 
                                        for (; --el >= 4; )
2859
 
                                                if (dpybuf[el] == '_')
2860
 
                                                        dpybuf[el] = '.';
2861
 
                                        break;
2862
 
                                }
2863
 
                }
2864
 
                key = XrmQuarkToString (quarks[1]);
2865
 
        } else
2866
 
                return False;
2867
 
        handleXdmVal( dpy, key, value->addr, dpyents, as(dpyents) );
2868
 
        return False;
 
2839
    if (*type != XrmQString)
 
2840
        return False;
 
2841
    if (*bindings == XrmBindLoosely ||
 
2842
            strcmp(XrmQuarkToString (*quarks), "DisplayManager"))
 
2843
        return False;
 
2844
    bindings++, quarks++;
 
2845
    if (!*quarks)
 
2846
        return False;
 
2847
    if (*bindings != XrmBindLoosely && !quarks[1]) { /* DM.foo */
 
2848
        key = XrmQuarkToString(*quarks);
 
2849
        handleXdmVal(0, key, value->addr, globents, as(globents));
 
2850
        return False;
 
2851
    } else if (*bindings == XrmBindLoosely && !quarks[1]) { /* DM*bar */
 
2852
        dpy = "*";
 
2853
        key = XrmQuarkToString(*quarks);
 
2854
    } else if (*bindings != XrmBindLoosely && quarks[1] &&
 
2855
               *bindings != XrmBindLoosely && !quarks[2])
 
2856
    { /* DM.foo.bar */
 
2857
        dpy = dpybuf + 4;
 
2858
        strcpy(dpybuf + 4, XrmQuarkToString(*quarks));
 
2859
        for (hasu = False, el = 4; dpybuf[el]; el++)
 
2860
            if (dpybuf[el] == '_')
 
2861
                hasu = True;
 
2862
        if (!hasu/* && isupper (dpy[0])*/) {
 
2863
            dpy = dpybuf;
 
2864
            memcpy(dpybuf, "*:*_", 4);
 
2865
        } else {
 
2866
            for (; --el >= 0;)
 
2867
                if (dpybuf[el] == '_') {
 
2868
                    dpybuf[el] = ':';
 
2869
                    for (; --el >= 4;)
 
2870
                        if (dpybuf[el] == '_')
 
2871
                            dpybuf[el] = '.';
 
2872
                    break;
 
2873
                }
 
2874
        }
 
2875
        key = XrmQuarkToString(quarks[1]);
 
2876
    } else {
 
2877
        return False;
 
2878
    }
 
2879
    handleXdmVal(dpy, key, value->addr, dpyents, as(dpyents));
 
2880
    return False;
2869
2881
}
2870
2882
 
2871
2883
static FDefs xdmdefs[] = {
2880
2892
};
2881
2893
 
2882
2894
static int
2883
 
mergeXdmCfg( const char *path )
 
2895
mergeXdmCfg(const char *path)
2884
2896
{
2885
 
        char *p;
2886
 
        XrmDatabase db;
 
2897
    char *p;
 
2898
    XrmDatabase db;
2887
2899
 
2888
 
        ASPrintf( &p, "%s/xdm-config", path );
2889
 
        if ((db = XrmGetFileDatabase( p ))) {
2890
 
                printf( "Information: reading xdm config file %s\n", p );
2891
 
                usedFile( p );
2892
 
                free( p );
2893
 
                XrmEnumerateDatabase( db, &empty, &empty, XrmEnumAllLevels,
2894
 
                                      dumpEntry, (XPointer)0 );
2895
 
                applyDefs( xdmdefs, as(xdmdefs), path );
2896
 
                mod_usebg = True;
2897
 
                return True;
2898
 
        }
2899
 
        free( p );
2900
 
        return False;
 
2900
    ASPrintf(&p, "%s/xdm-config", path);
 
2901
    if ((db = XrmGetFileDatabase(p))) {
 
2902
        printf("Information: reading xdm config file %s\n", p);
 
2903
        usedFile(p);
 
2904
        free(p);
 
2905
        XrmEnumerateDatabase(db, &empty, &empty, XrmEnumAllLevels,
 
2906
                             dumpEntry, (XPointer)0);
 
2907
        applyDefs(xdmdefs, as(xdmdefs), path);
 
2908
        mod_usebg = True;
 
2909
        return True;
 
2910
    }
 
2911
    free(p);
 
2912
    return False;
2901
2913
}
2902
2914
 
2903
2915
static void
2904
 
fprintfLineWrap( FILE *f, const char *msg, ... )
 
2916
fprintfLineWrap(FILE *f, const char *msg, ...)
2905
2917
{
2906
 
        char *txt, *ftxt, *line;
2907
 
        va_list ap;
2908
 
        int col, lword, fspace;
 
2918
    char *txt, *ftxt, *line;
 
2919
    va_list ap;
 
2920
    int col, lword, fspace;
2909
2921
 
2910
 
        va_start( ap, msg );
2911
 
        VASPrintf( &txt, msg, ap );
2912
 
        va_end( ap );
2913
 
        ftxt = 0;
2914
 
        for (line = txt, col = 0, lword = fspace = -1; line[col]; ) {
2915
 
                if (line[col] == '\n') {
2916
 
                        strCat( &ftxt, "%.*s", ++col, line );
2917
 
                        line += col;
2918
 
                        col = 0;
2919
 
                        lword = fspace = -1;
2920
 
                        continue;
2921
 
                } else if (line[col] == ' ') {
2922
 
                        if (lword >= 0) {
2923
 
                                fspace = col;
2924
 
                                lword = -1;
2925
 
                        }
2926
 
                } else {
2927
 
                        if (lword < 0)
2928
 
                                lword = col;
2929
 
                        if (col >= 78 && fspace >= 0) {
2930
 
                                strCat( &ftxt, "%.*s\n", fspace, line );
2931
 
                                line += lword;
2932
 
                                col -= lword;
2933
 
                                lword = 0;
2934
 
                                fspace = -1;
2935
 
                        }
2936
 
                }
2937
 
                col++;
2938
 
        }
2939
 
        free( txt );
2940
 
        if (ftxt) {
2941
 
                fputs_( ftxt, f );
2942
 
                free( ftxt );
2943
 
        }
 
2922
    va_start(ap, msg);
 
2923
    VASPrintf(&txt, msg, ap);
 
2924
    va_end(ap);
 
2925
    ftxt = 0;
 
2926
    for (line = txt, col = 0, lword = fspace = -1; line[col];) {
 
2927
        if (line[col] == '\n') {
 
2928
            strCat(&ftxt, "%.*s", ++col, line);
 
2929
            line += col;
 
2930
            col = 0;
 
2931
            lword = fspace = -1;
 
2932
            continue;
 
2933
        } else if (line[col] == ' ') {
 
2934
            if (lword >= 0) {
 
2935
                fspace = col;
 
2936
                lword = -1;
 
2937
            }
 
2938
        } else {
 
2939
            if (lword < 0)
 
2940
                lword = col;
 
2941
            if (col >= 78 && fspace >= 0) {
 
2942
                strCat(&ftxt, "%.*s\n", fspace, line);
 
2943
                line += lword;
 
2944
                col -= lword;
 
2945
                lword = 0;
 
2946
                fspace = -1;
 
2947
            }
 
2948
        }
 
2949
        col++;
 
2950
    }
 
2951
    free(txt);
 
2952
    if (ftxt) {
 
2953
        fputs_(ftxt, f);
 
2954
        free(ftxt);
 
2955
    }
2944
2956
}
2945
2957
 
2946
2958
 
2947
2959
static const char * const oldkdes[] = {
2948
 
        KDM_CONFDIR,
2949
 
        KDE_CONFDIR,
2950
 
        "/opt/kde4/share/config",
2951
 
        "/usr/local/kde4/share/config",
2952
 
 
2953
 
        "/opt/kde/share/config",
2954
 
        "/usr/local/kde/share/config",
2955
 
        "/usr/local/share/config",
2956
 
        "/usr/share/config",
2957
 
        "/etc/kde3",
2958
 
 
2959
 
        "/opt/kde3/share/config",
2960
 
        "/usr/local/kde3/share/config",
 
2960
    KDE_CONFDIR,
 
2961
    "/opt/kde4/share/config",
 
2962
    "/usr/local/kde4/share/config",
 
2963
 
 
2964
    "/opt/kde/share/config",
 
2965
    "/usr/local/kde/share/config",
 
2966
    "/usr/local/share/config",
 
2967
    "/usr/share/config",
 
2968
 
 
2969
    "/opt/kde3/share/config",
 
2970
    "/usr/local/kde3/share/config",
2961
2971
};
2962
2972
 
2963
2973
static const char * const oldxdms[] = {
2964
 
        "/etc/X11/xdm",
2965
 
        XLIBDIR "/xdm",
 
2974
    "/etc/X11/xdm",
 
2975
    XLIBDIR "/xdm",
2966
2976
};
2967
2977
 
2968
 
int main( int argc, char **argv )
 
2978
int main(int argc, char **argv)
2969
2979
{
2970
 
        const char **where;
2971
 
        FILE *f;
2972
 
        StrList *fp;
2973
 
        Section *cs;
2974
 
        Entry *ce, **cep;
2975
 
        int i, ap, locals, foreigns;
2976
 
        int no_old_xdm = 0, no_old_kde = 0;
2977
 
        struct stat st;
 
2980
    const char **where;
 
2981
    FILE *f;
 
2982
    StrList *fp;
 
2983
    Section *cs;
 
2984
    Entry *ce, **cep;
 
2985
    int i, ap, locals, foreigns;
 
2986
    int no_old_xdm = 0, no_old_kde = 0;
 
2987
    struct stat st;
2978
2988
 
2979
 
        for (ap = 1; ap < argc; ap++) {
2980
 
                if (!strcmp( argv[ap], "--help" )) {
2981
 
                        printf(
 
2989
    for (ap = 1; ap < argc; ap++) {
 
2990
        if (!strcmp(argv[ap], "--help")) {
 
2991
            printf(
2982
2992
"genkdmconf - generate configuration files for kdm\n"
2983
2993
"\n"
2984
2994
"If an older xdm/kdm configuration is found, its config files are \"absorbed\";\n"
2998
3008
"    Note that you possibly need to use --no-old-kde to make this take effect.\n"
2999
3009
"  --old-kde /path/to/old/kde-config-dir\n"
3000
3010
"    Where to look for the kdmrc of a previously installed kdm.\n"
3001
 
"    Default is to scan " KDM_CONFDIR " and\n"
 
3011
"    Default is to scan " KDE_CONFDIR " and\n"
3002
3012
"    {/usr,/usr/local,{/opt,/usr/local}/{kde4,kde,kde3}}/share/config.\n"
3003
3013
"  --no-old\n"
3004
3014
"    Do not look at older xdm/kdm configurations, just create default config.\n"
3019
3029
"  --no-in-notice\n"
3020
3030
"    Do not put the notice about --in being used into the generated README.\n"
3021
3031
);
3022
 
                        exit( 0 );
3023
 
                }
3024
 
                if (!strcmp( argv[ap], "--no-old" )) {
3025
 
                        no_old = True;
3026
 
                        continue;
3027
 
                }
3028
 
                if (!strcmp( argv[ap], "--old-scripts" )) {
3029
 
                        old_scripts = True;
3030
 
                        continue;
3031
 
                }
3032
 
                if (!strcmp( argv[ap], "--no-old-scripts" )) {
3033
 
                        no_old_scripts = True;
3034
 
                        continue;
3035
 
                }
3036
 
                if (!strcmp( argv[ap], "--old-confs" )) {
3037
 
                        old_confs = True;
3038
 
                        continue;
3039
 
                }
3040
 
                if (!strcmp( argv[ap], "--no-old-xdm" )) {
3041
 
                        no_old_xdm = True;
3042
 
                        continue;
3043
 
                }
3044
 
                if (!strcmp( argv[ap], "--no-old-kde" )) {
3045
 
                        no_old_kde = True;
3046
 
                        continue;
3047
 
                }
3048
 
                if (!strcmp( argv[ap], "--no-backup" )) {
3049
 
                        no_backup = True;
3050
 
                        continue;
3051
 
                }
3052
 
                if (!strcmp( argv[ap], "--no-in-notice" )) {
3053
 
                        no_in_notice = True;
3054
 
                        continue;
3055
 
                }
3056
 
                where = 0;
3057
 
                if (!strcmp( argv[ap], "--in" ))
3058
 
                        where = &newdir;
3059
 
                else if (!strcmp( argv[ap], "--old-xdm" ))
3060
 
                        where = &oldxdm;
3061
 
                else if (!strcmp( argv[ap], "--old-kde" ))
3062
 
                        where = &oldkde;
3063
 
                else if (!strcmp( argv[ap], "--face-src" ))
3064
 
                        where = &facesrc;
3065
 
                else {
3066
 
                        fprintf( stderr, "Unknown command line option '%s', try --help\n", argv[ap] );
3067
 
                        exit( 1 );
3068
 
                }
3069
 
                if (ap + 1 == argc || argv[ap + 1][0] == '-') {
3070
 
                        fprintf( stderr, "Missing argument to option '%s', try --help\n", argv[ap] );
3071
 
                        exit( 1 );
3072
 
                }
3073
 
                *where = argv[++ap];
3074
 
        }
3075
 
        if (memcmp( newdir, KDMCONF, sizeof(KDMCONF) ))
3076
 
                use_destdir = True;
3077
 
 
3078
 
        if (!mkdirp( newdir, 0755, "target", True ))
3079
 
                exit( 1 );
3080
 
 
3081
 
        makeDefaultConfig();
3082
 
        if (no_old) {
3083
 
                DIR *dir;
3084
 
                StrList *bfl = 0;
3085
 
                if ((dir = opendir( newdir ))) {
3086
 
                        struct dirent *ent;
3087
 
                        char bn[PATH_MAX];
3088
 
                        while ((ent = readdir( dir ))) {
3089
 
                                int l;
3090
 
                                if (!strcmp( ent->d_name, "." ) || !strcmp( ent->d_name, ".." ))
3091
 
                                        continue;
3092
 
                                l = sprintf( bn, "%s/%s", newdir, ent->d_name ); /* cannot overflow (kernel would not allow the creation of a longer path) */
3093
 
                                if (!stat( bn, &st ) && !S_ISREG( st.st_mode ))
3094
 
                                        continue;
3095
 
                                if (no_backup || !memcmp( bn + l - 4, ".bak", 5 ))
3096
 
                                        unlink( bn );
3097
 
                                else
3098
 
                                        addStr( &bfl, bn );
3099
 
                        }
3100
 
                        closedir( dir );
3101
 
                        for (; bfl; bfl = bfl->next)
3102
 
                                displace( bfl->str );
3103
 
                }
3104
 
        } else {
3105
 
                if (oldkde) {
3106
 
                        if (!mergeKdmRcNewer( oldkde, True ) && !mergeKdmRcOld( oldkde )) {
3107
 
                                fprintf( stderr,
3108
 
                                         "Cannot read pre-existing kdmrc at specified location\n" );
3109
 
                                oldkde = 0;
3110
 
                        }
3111
 
                } else if (!no_old_kde) {
3112
 
                        for (i = 0; i < as(oldkdes); i++) {
3113
 
                                if (i && !strcmp( oldkdes[0], oldkdes[i] ))
3114
 
                                        continue;
3115
 
                                if (mergeKdmRcNewer( oldkdes[i], 0 )) {
3116
 
                                        oldkde = oldkdes[i];
3117
 
                                        break;
3118
 
                                }
3119
 
                                mergeKdmRcOld( oldkdes[i] ); /* only prints a message */
3120
 
                        }
3121
 
                }
3122
 
                if (oldkde) {
 
3032
            exit(0);
 
3033
        }
 
3034
        if (!strcmp(argv[ap], "--no-old")) {
 
3035
            no_old = True;
 
3036
            continue;
 
3037
        }
 
3038
        if (!strcmp(argv[ap], "--old-scripts")) {
 
3039
            old_scripts = True;
 
3040
            continue;
 
3041
        }
 
3042
        if (!strcmp(argv[ap], "--no-old-scripts")) {
 
3043
            no_old_scripts = True;
 
3044
            continue;
 
3045
        }
 
3046
        if (!strcmp(argv[ap], "--old-confs")) {
 
3047
            old_confs = True;
 
3048
            continue;
 
3049
        }
 
3050
        if (!strcmp(argv[ap], "--no-old-xdm")) {
 
3051
            no_old_xdm = True;
 
3052
            continue;
 
3053
        }
 
3054
        if (!strcmp(argv[ap], "--no-old-kde")) {
 
3055
            no_old_kde = True;
 
3056
            continue;
 
3057
        }
 
3058
        if (!strcmp(argv[ap], "--no-backup")) {
 
3059
            no_backup = True;
 
3060
            continue;
 
3061
        }
 
3062
        if (!strcmp(argv[ap], "--no-in-notice")) {
 
3063
            no_in_notice = True;
 
3064
            continue;
 
3065
        }
 
3066
        where = 0;
 
3067
        if (!strcmp(argv[ap], "--in")) {
 
3068
            where = &newdir;
 
3069
        } else if (!strcmp(argv[ap], "--old-xdm")) {
 
3070
            where = &oldxdm;
 
3071
        } else if (!strcmp(argv[ap], "--old-kde")) {
 
3072
            where = &oldkde;
 
3073
        } else if (!strcmp(argv[ap], "--face-src")) {
 
3074
            where = &facesrc;
 
3075
        } else {
 
3076
            fprintf(stderr, "Unknown command line option '%s', try --help\n", argv[ap]);
 
3077
            exit(1);
 
3078
        }
 
3079
        if (ap + 1 == argc || argv[ap + 1][0] == '-') {
 
3080
            fprintf(stderr, "Missing argument to option '%s', try --help\n", argv[ap]);
 
3081
            exit(1);
 
3082
        }
 
3083
        *where = argv[++ap];
 
3084
    }
 
3085
    if (memcmp(newdir, KDMCONF, sizeof(KDMCONF)))
 
3086
        use_destdir = True;
 
3087
 
 
3088
    if (!mkdirp(newdir, 0755, "target", True))
 
3089
        exit(1);
 
3090
 
 
3091
    makeDefaultConfig();
 
3092
    if (no_old) {
 
3093
        DIR *dir;
 
3094
        StrList *bfl = 0;
 
3095
        if ((dir = opendir(newdir))) {
 
3096
            struct dirent *ent;
 
3097
            char bn[PATH_MAX];
 
3098
            while ((ent = readdir(dir))) {
 
3099
                int l;
 
3100
                if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
 
3101
                    continue;
 
3102
                l = sprintf(bn, "%s/%s", newdir, ent->d_name); /* cannot overflow (kernel would not allow the creation of a longer path) */
 
3103
                if (!stat(bn, &st) && !S_ISREG(st.st_mode))
 
3104
                    continue;
 
3105
                if (no_backup || !memcmp(bn + l - 4, ".bak", 5))
 
3106
                    unlink(bn);
 
3107
                else
 
3108
                    addStr(&bfl, bn);
 
3109
            }
 
3110
            closedir(dir);
 
3111
            for (; bfl; bfl = bfl->next)
 
3112
                displace(bfl->str);
 
3113
        }
 
3114
    } else {
 
3115
        if (oldkde) {
 
3116
            if (!mergeKdmRcNewer(oldkde, True) && !mergeKdmRcOld(oldkde)) {
 
3117
                fprintf(stderr,
 
3118
                        "Cannot read pre-existing kdmrc at specified location\n");
 
3119
                oldkde = 0;
 
3120
            }
 
3121
        } else if (!no_old_kde) {
 
3122
            for (i = 0; i < as(oldkdes); i++) {
 
3123
                if (i && !strcmp(oldkdes[0], oldkdes[i]))
 
3124
                    continue;
 
3125
                if (mergeKdmRcNewer(oldkdes[i], 0)) {
 
3126
                    oldkde = oldkdes[i];
 
3127
                    break;
 
3128
                }
 
3129
                mergeKdmRcOld(oldkdes[i]); /* only prints a message */
 
3130
            }
 
3131
        }
 
3132
        if (oldkde) {
3123
3133
#define SHR_CONF "/share/config"
3124
 
                        int olen = strlen( oldkde );
3125
 
                        if (olen < (int)sizeof(SHR_CONF) ||
3126
 
                                memcmp( oldkde + olen - sizeof(SHR_CONF) + 1,
3127
 
                                                SHR_CONF, sizeof(SHR_CONF) ))
3128
 
                        {
3129
 
                                fprintf( stderr,
3130
 
                                         "Warning: --old-kde does not end with " SHR_CONF ". "
3131
 
                                         "Might wreak havoc.\n" );
3132
 
                                oldkdepfx = oldkde;
3133
 
                        } else
3134
 
                                ASPrintf( (char **)&oldkdepfx,
3135
 
                                           "%.*s", olen - sizeof(SHR_CONF) + 1, oldkde );
3136
 
                        oldxdm = 0;
3137
 
                } else if (!no_old_xdm) {
3138
 
                        XrmInitialize();
3139
 
                        XrmQString = XrmPermStringToQuark( "String" );
3140
 
                        if (oldxdm) {
3141
 
                                if (!mergeXdmCfg( oldxdm )) {
3142
 
                                        fprintf( stderr,
3143
 
                                                 "Cannot read xdm-config at specified location\n" );
3144
 
                                        oldxdm = 0;
3145
 
                                }
3146
 
                        } else
3147
 
                                for (i = 0; i < as(oldxdms); i++)
3148
 
                                        if (mergeXdmCfg( oldxdms[i] )) {
3149
 
                                                oldxdm = oldxdms[i];
3150
 
                                                break;
3151
 
                                        }
3152
 
                }
3153
 
        }
3154
 
        /*
3155
 
         * How to proceed with pre-existing scripts (which are named in the config):
3156
 
         * - old_scripts set or some scripts in new target already => keep 'em
3157
 
         * - no_old_scripts set or all scripts outside new target => pretend that
3158
 
         *   the old config did not reference them in the first place
3159
 
         */
3160
 
        if (no_old_scripts)
3161
 
                goto no_old_s;
3162
 
        if (!old_scripts) {
3163
 
                locals = foreigns = False;
3164
 
                for (cs = config; cs; cs = cs->next)
3165
 
                        if (!strcmp( cs->spec->name, "-Core" )) {
3166
 
                                for (ce = cs->ents; ce; ce = ce->next)
3167
 
                                        if (ce->active &&
3168
 
                                            (!strcmp( ce->spec->key, "Setup" ) ||
3169
 
                                             !strcmp( ce->spec->key, "Startup" ) ||
3170
 
                                             !strcmp( ce->spec->key, "Reset" )))
3171
 
                                        {
3172
 
                                                if (inNewDir( ce->value ))
3173
 
                                                        locals = True;
3174
 
                                                else
3175
 
                                                        foreigns = True;
3176
 
                                        }
3177
 
                        }
3178
 
                if (foreigns) {
3179
 
                        if (locals) {
3180
 
                                fprintf( stderr,
3181
 
                                         "Warning: both local and foreign scripts referenced. "
3182
 
                                         "Will not touch any.\n" );
3183
 
                                mixed_scripts = True;
3184
 
                        } else {
3185
 
                          no_old_s:
3186
 
                                for (cs = config; cs; cs = cs->next) {
3187
 
                                        if (!strcmp( cs->spec->name, "Xdmcp" )) {
3188
 
                                                for (ce = cs->ents; ce; ce = ce->next)
3189
 
                                                        if (!strcmp( ce->spec->key, "Willing" ))
3190
 
                                                                ce->active = ce->written = False;
3191
 
                                        } else if (!strcmp( cs->spec->name, "-Core" )) {
3192
 
                                                for (cep = &cs->ents; (ce = *cep); ) {
3193
 
                                                        if (ce->active &&
3194
 
                                                            (!strcmp( ce->spec->key, "Setup" ) ||
3195
 
                                                             !strcmp( ce->spec->key, "Startup" ) ||
3196
 
                                                             !strcmp( ce->spec->key, "Reset" ) ||
3197
 
                                                             !strcmp( ce->spec->key, "Session" )))
3198
 
                                                        {
3199
 
                                                                if (!memcmp( cs->name, "X-*-", 4 ))
3200
 
                                                                        ce->active = ce->written = False;
3201
 
                                                                else {
3202
 
                                                                        *cep = ce->next;
3203
 
                                                                        free( ce );
3204
 
                                                                        continue;
3205
 
                                                                }
3206
 
                                                        }
3207
 
                                                        cep = &ce->next;
3208
 
                                                }
3209
 
                                        }
3210
 
                                }
3211
 
                        }
3212
 
                }
3213
 
        }
 
3134
            int olen = strlen(oldkde);
 
3135
            if (olen < (int)sizeof(SHR_CONF) ||
 
3136
                memcmp(oldkde + olen - sizeof(SHR_CONF) + 1,
 
3137
                       SHR_CONF, sizeof(SHR_CONF)))
 
3138
            {
 
3139
                /*
 
3140
                fprintf(stderr,
 
3141
                        "Warning: --old-kde does not end with " SHR_CONF ". "
 
3142
                        "Might wreak havoc.\n");
 
3143
                */
 
3144
                oldkdepfx = oldkde;
 
3145
            } else
 
3146
                ASPrintf((char **)&oldkdepfx,
 
3147
                         "%.*s", olen - sizeof(SHR_CONF) + 1, oldkde);
 
3148
            oldxdm = 0;
 
3149
        } else if (!no_old_xdm) {
 
3150
            XrmInitialize();
 
3151
            XrmQString = XrmPermStringToQuark("String");
 
3152
            if (oldxdm) {
 
3153
                if (!mergeXdmCfg(oldxdm)) {
 
3154
                    fprintf(stderr,
 
3155
                            "Cannot read xdm-config at specified location\n");
 
3156
                    oldxdm = 0;
 
3157
                }
 
3158
            } else
 
3159
                for (i = 0; i < as(oldxdms); i++)
 
3160
                    if (mergeXdmCfg(oldxdms[i])) {
 
3161
                        oldxdm = oldxdms[i];
 
3162
                        break;
 
3163
                    }
 
3164
        }
 
3165
    }
 
3166
    /*
 
3167
     * How to proceed with pre-existing scripts (which are named in the config):
 
3168
     * - old_scripts set or some scripts in new target already => keep 'em
 
3169
     * - no_old_scripts set or all scripts outside new target => pretend that
 
3170
     *   the old config did not reference them in the first place
 
3171
     */
 
3172
    if (no_old_scripts)
 
3173
        goto no_old_s;
 
3174
    if (!old_scripts) {
 
3175
        locals = foreigns = False;
 
3176
        for (cs = config; cs; cs = cs->next)
 
3177
            if (!strcmp(cs->spec->name, "-Core")) {
 
3178
                for (ce = cs->ents; ce; ce = ce->next)
 
3179
                    if (ce->active &&
 
3180
                        (!strcmp(ce->spec->key, "Setup") ||
 
3181
                         !strcmp(ce->spec->key, "Startup") ||
 
3182
                         !strcmp(ce->spec->key, "Reset")))
 
3183
                    {
 
3184
                        if (inNewDir(ce->value))
 
3185
                            locals = True;
 
3186
                        else
 
3187
                            foreigns = True;
 
3188
                    }
 
3189
            }
 
3190
        if (foreigns) {
 
3191
            if (locals) {
 
3192
                fprintf(stderr,
 
3193
                        "Warning: both local and foreign scripts referenced. "
 
3194
                        "Will not touch any.\n");
 
3195
                mixed_scripts = True;
 
3196
            } else {
 
3197
              no_old_s:
 
3198
                for (cs = config; cs; cs = cs->next) {
 
3199
                    if (!strcmp(cs->spec->name, "Xdmcp")) {
 
3200
                        for (ce = cs->ents; ce; ce = ce->next)
 
3201
                            if (!strcmp(ce->spec->key, "Willing"))
 
3202
                                ce->active = ce->written = False;
 
3203
                    } else if (!strcmp(cs->spec->name, "-Core")) {
 
3204
                        for (cep = &cs->ents; (ce = *cep);) {
 
3205
                            if (ce->active &&
 
3206
                                (!strcmp(ce->spec->key, "Setup") ||
 
3207
                                 !strcmp(ce->spec->key, "Startup") ||
 
3208
                                 !strcmp(ce->spec->key, "Reset") ||
 
3209
                                 !strcmp(ce->spec->key, "Session")))
 
3210
                            {
 
3211
                                if (!memcmp(cs->name, "X-*-", 4)) {
 
3212
                                    ce->active = ce->written = False;
 
3213
                                } else {
 
3214
                                    *cep = ce->next;
 
3215
                                    free(ce);
 
3216
                                    continue;
 
3217
                                }
 
3218
                            }
 
3219
                            cep = &ce->next;
 
3220
                        }
 
3221
                    }
 
3222
                }
 
3223
            }
 
3224
        }
 
3225
    }
3214
3226
#ifdef __linux__
3215
 
        if (!stat( "/etc/debian_version", &st )) { /* debian */
3216
 
                defminuid = "1000";
3217
 
                defmaxuid = "29999";
3218
 
        } else if (!stat( "/usr/portage", &st )) { /* gentoo */
3219
 
                defminuid = "1000";
3220
 
                defmaxuid = "65000";
3221
 
        } else if (!stat( "/etc/mandrake-release", &st )) { /* mandrake - check before redhat! */
3222
 
                defminuid = "500";
3223
 
                defmaxuid = "65000";
3224
 
        } else if (!stat( "/etc/redhat-release", &st )) { /* redhat */
3225
 
                defminuid = "100";
3226
 
                defmaxuid = "65000";
3227
 
        } else /* if (!stat( "/etc/SuSE-release", &st )) */ { /* suse */
3228
 
                defminuid = "500";
3229
 
                defmaxuid = "65000";
3230
 
        }
 
3227
    if (!stat("/etc/debian_version", &st)) { /* debian */
 
3228
        defminuid = "1000";
 
3229
        defmaxuid = "29999";
 
3230
    } else if (!stat("/usr/portage", &st)) { /* gentoo */
 
3231
        defminuid = "1000";
 
3232
        defmaxuid = "65000";
 
3233
    } else if (!stat("/etc/mandrake-release", &st)) { /* mandrake - check before redhat! */
 
3234
        defminuid = "500";
 
3235
        defmaxuid = "65000";
 
3236
    } else if (!stat("/etc/redhat-release", &st)) { /* redhat */
 
3237
        defminuid = "100";
 
3238
        defmaxuid = "65000";
 
3239
    } else /* if (!stat("/etc/SuSE-release", &st)) */ { /* suse */
 
3240
        defminuid = "500";
 
3241
        defmaxuid = "65000";
 
3242
    }
3231
3243
#else
3232
 
        defminuid = "1000";
3233
 
        defmaxuid = "65000";
 
3244
    defminuid = "1000";
 
3245
    defmaxuid = "65000";
3234
3246
#endif
3235
 
        for (i = 0; i <= CONF_MAX_PRIO; i++)
3236
 
                for (cs = config; cs; cs = cs->next)
3237
 
                        for (ce = cs->ents; ce; ce = ce->next)
3238
 
                                if (ce->spec->func && i == ce->spec->prio)
3239
 
                                        ce->spec->func( ce, cs );
3240
 
        f = createFile( "kdmrc", kdmrcmode );
3241
 
        writeKdmrc( f );
3242
 
        fclose_( f );
 
3247
    for (i = 0; i <= CONF_MAX_PRIO; i++)
 
3248
        for (cs = config; cs; cs = cs->next)
 
3249
            for (ce = cs->ents; ce; ce = ce->next)
 
3250
                if (ce->spec->func && i == ce->spec->prio)
 
3251
                    ce->spec->func(ce, cs);
 
3252
    f = createFile("kdmrc", kdmrcmode);
 
3253
    writeKdmrc(f);
 
3254
    fclose_(f);
3243
3255
 
3244
 
        f = createFile( "README", 0644 );
3245
 
        fprintf_( f,
3246
 
"This automatically generated configuration consists of the following files:\n" );
3247
 
        fprintf_( f, "- " KDMCONF "/kdmrc\n" );
3248
 
        for (fp = aflist; fp; fp = fp->next)
3249
 
                fprintf_( f, "- %s\n", fp->str );
3250
 
        if (use_destdir && !no_in_notice)
3251
 
                fprintfLineWrap( f,
 
3256
    f = createFile("README", 0644);
 
3257
    fprintf_(f,
 
3258
"This automatically generated configuration consists of the following files:\n");
 
3259
    fprintf_(f, "- " KDMCONF "/kdmrc\n");
 
3260
    for (fp = aflist; fp; fp = fp->next)
 
3261
        fprintf_(f, "- %s\n", fp->str);
 
3262
    if (use_destdir && !no_in_notice)
 
3263
        fprintfLineWrap(f,
3252
3264
"All files destined for " KDMCONF " were actually saved in %s; "
3253
 
"this config will not be workable until moved in place.\n", newdir );
3254
 
        if (uflist || eflist || cflist || lflist) {
3255
 
                fprintf_( f,
 
3265
"this config will not be workable until moved in place.\n", newdir);
 
3266
    if (uflist || eflist || cflist || lflist) {
 
3267
        fprintf_(f,
3256
3268
"\n"
3257
3269
"This config was derived from existing files. As the used algorithms are\n"
3258
 
"pretty dumb, it may be broken.\n" );
3259
 
                if (uflist) {
3260
 
                        fprintf_( f,
3261
 
"Information from these files was extracted:\n" );
3262
 
                        for (fp = uflist; fp; fp = fp->next)
3263
 
                                fprintf_( f, "- %s\n", fp->str );
3264
 
                }
3265
 
                if (lflist) {
3266
 
                        fprintf_( f,
3267
 
"These files were directly incorporated:\n" );
3268
 
                        for (fp = lflist; fp; fp = fp->next)
3269
 
                                fprintf_( f, "- %s\n", fp->str );
3270
 
                }
3271
 
                if (cflist) {
3272
 
                        fprintf_( f,
3273
 
"These files were copied verbatim:\n" );
3274
 
                        for (fp = cflist; fp; fp = fp->next)
3275
 
                                fprintf_( f, "- %s\n", fp->str );
3276
 
                }
3277
 
                if (eflist) {
3278
 
                        fprintf_( f,
3279
 
"These files were copied with modifications:\n" );
3280
 
                        for (fp = eflist; fp; fp = fp->next)
3281
 
                                fprintf_( f, "- %s\n", fp->str );
3282
 
                }
3283
 
                if (!no_backup && !use_destdir)
3284
 
                        fprintf_( f,
3285
 
"Old files that would have been overwritten were renamed to <oldname>.bak.\n" );
3286
 
        }
3287
 
        fprintf_( f,
 
3270
"pretty dumb, it may be broken.\n");
 
3271
        if (uflist) {
 
3272
            fprintf_(f,
 
3273
"Information from these files was extracted:\n");
 
3274
            for (fp = uflist; fp; fp = fp->next)
 
3275
                fprintf_(f, "- %s\n", fp->str);
 
3276
        }
 
3277
        if (lflist) {
 
3278
            fprintf_(f,
 
3279
"These files were directly incorporated:\n");
 
3280
            for (fp = lflist; fp; fp = fp->next)
 
3281
                fprintf_(f, "- %s\n", fp->str);
 
3282
        }
 
3283
        if (cflist) {
 
3284
            fprintf_(f,
 
3285
"These files were copied verbatim:\n");
 
3286
            for (fp = cflist; fp; fp = fp->next)
 
3287
                fprintf_(f, "- %s\n", fp->str);
 
3288
        }
 
3289
        if (eflist) {
 
3290
            fprintf_(f,
 
3291
"These files were copied with modifications:\n");
 
3292
            for (fp = eflist; fp; fp = fp->next)
 
3293
                fprintf_(f, "- %s\n", fp->str);
 
3294
        }
 
3295
        if (!no_backup && !use_destdir)
 
3296
            fprintf_(f,
 
3297
"Old files that would have been overwritten were renamed to <oldname>.bak.\n");
 
3298
    }
 
3299
    fprintf_(f,
3288
3300
"\nTry 'genkdmconf --help' if you want to generate another configuration.\n"
3289
 
"\nYou may delete this README.\n" );
3290
 
        fclose_( f );
 
3301
"\nYou may delete this README.\n");
 
3302
    fclose_(f);
3291
3303
 
3292
 
        return 0;
 
3304
    return 0;
3293
3305
}