~ubuntu-branches/ubuntu/karmic/x11-xserver-utils/karmic

« back to all changes in this revision

Viewing changes to sessreg/sessreg.c

  • Committer: Bazaar Package Importer
  • Author(s): Brice Goglin, Julien Cristau, Brice Goglin
  • Date: 2007-08-17 09:58:34 UTC
  • Revision ID: james.westby@ubuntu.com-20070817095834-ywge2nyzj1s3rqnd
Tags: 7.3+1
[ Julien Cristau ]
* iceauth 1.0.2.
  + removes blank line in the manpage (closes: #25285).
* xmodmap 1.0.3.
  + manpage updated to state that -pm is the default (closes: #236198)
* xgamma 1.0.2.
  + the manpage now explains how to print the gamma value more clearly
    (closes: #296021).
* xsetroot 1.0.2.
* xrdb 1.0.4.
  + fixes manpage typo (closes: #276286).
* Add upstream URL to debian/copyright, and update it from xgamma's COPYING
  file.

[ Brice Goglin ]
* Add menu entries for xrefresh and xvidtune.
* sessreg 1.0.3.
* xset 1.0.3.
* Add myself to Uploaders, and remove Branden with his permission.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Xorg: sessreg.c,v 1.5 2000/08/17 19:54:15 cpqbld Exp $
 
3
 * $XdotOrg: $
 
4
 *
 
5
 * Copyright 1990, 1998  The Open Group
 
6
 *
 
7
 * Permission to use, copy, modify, distribute, and sell this software and its
 
8
 * documentation for any purpose is hereby granted without fee, provided that
 
9
 * the above copyright notice appear in all copies and that both that
 
10
 * copyright notice and this permission notice appear in supporting
 
11
 * documentation.
 
12
 * 
 
13
 * The above copyright notice and this permission notice shall be included
 
14
 * in all copies or substantial portions of the Software.
 
15
 * 
 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
17
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
18
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 
19
 * IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
 
20
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 
21
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 
22
 * OTHER DEALINGS IN THE SOFTWARE.
 
23
 * 
 
24
 * Except as contained in this notice, the name of The Open Group shall
 
25
 * not be used in advertising or otherwise to promote the sale, use or
 
26
 * other dealings in this Software without prior written authorization
 
27
 * from The Open Group.
 
28
 *
 
29
 */
 
30
 
 
31
/* Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 
32
 *
 
33
 * Permission is hereby granted, free of charge, to any person obtaining a
 
34
 * copy of this software and associated documentation files (the
 
35
 * "Software"), to deal in the Software without restriction, including
 
36
 * without limitation the rights to use, copy, modify, merge, publish,
 
37
 * distribute, and/or sell copies of the Software, and to permit persons
 
38
 * to whom the Software is furnished to do so, provided that the above
 
39
 * copyright notice(s) and this permission notice appear in all copies of
 
40
 * the Software and that both the above copyright notice(s) and this
 
41
 * permission notice appear in supporting documentation.
 
42
 * 
 
43
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
44
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
45
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
 
46
 * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 
47
 * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
 
48
 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
 
49
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 
50
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 
51
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
52
 * 
 
53
 * Except as contained in this notice, the name of a copyright holder
 
54
 * shall not be used in advertising or otherwise to promote the sale, use
 
55
 * or other dealings in this Software without prior written authorization
 
56
 * of the copyright holder.
 
57
 */
 
58
 
 
59
/*
 
60
 * Author:  Keith Packard, MIT X Consortium
 
61
 * Lastlog support and dynamic utmp entry allocation
 
62
 *   by Andreas Stolcke <stolcke@icsi.berkeley.edu>
 
63
 */
 
64
 
 
65
/* $XFree86: xc/programs/xdm/sessreg.c,v 3.18 2001/12/14 20:01:24 dawes Exp $ */
 
66
 
 
67
/*
 
68
 * sessreg
 
69
 *
 
70
 * simple wtmp/utmp frobber
 
71
 *
 
72
 * usage: sessreg [ -w <wtmp-file> ] [ -u <utmp-file> ]
 
73
 *                [ -l <line> ]
 
74
 *                [ -h <host-name> ]                            / BSD only
 
75
 *                [ -s <slot-number> ] [ -x Xservers-file ]     / BSD only
 
76
 *                [ -t <ttys-file> ]                            / BSD only
 
77
 *                [ -a ] [ -d ] user-name
 
78
 *
 
79
 * one of -a or -d must be specified
 
80
 */
 
81
 
 
82
#ifdef HAVE_CONFIG_H
 
83
#include "config.h"
 
84
#endif
 
85
 
 
86
# include       <X11/Xos.h>
 
87
# include       <X11/Xfuncs.h>
 
88
# include       <stdio.h>
 
89
# include       <stdlib.h>
 
90
# include       <utmp.h>
 
91
 
 
92
#ifndef HAVE_CONFIG_H /* Imake fallback - hardcode platforms with utmpx */
 
93
# if (defined(sun) && defined (__SVR4))
 
94
#  define HAVE_UTMPX_H
 
95
#  define HAVE_UTMPX_UT_SYSLEN 1
 
96
# endif
 
97
#endif
 
98
 
 
99
#ifdef HAVE_UTMPX_H
 
100
# if HAVE_UTMPX_UT_SYSLEN
 
101
#  include <utmpx.h>
 
102
#  define USE_UTMPX
 
103
# endif
 
104
#endif
 
105
 
 
106
#ifdef HAVE_CONFIG_H
 
107
# ifndef HAVE_LASTLOG_H
 
108
#  define NO_LASTLOG
 
109
# endif
 
110
#else /* Imake */
 
111
# if defined(SYSV) || (defined(SVR4) && !defined(sun)) || defined(Lynx) || defined(__QNX__) || defined(__DARWIN__) || defined(_SEQUENT_)
 
112
#  define NO_LASTLOG
 
113
# endif
 
114
#endif
 
115
 
 
116
#if defined(CSRG_BASED) || defined(HAVE_SYS_PARAM_H)
 
117
#include <sys/param.h>
 
118
#endif
 
119
 
 
120
#ifndef NO_LASTLOG
 
121
# ifdef CSRG_BASED
 
122
#  if (BSD < 199103)
 
123
#   include     <lastlog.h>
 
124
#  endif
 
125
# else
 
126
#  include      <lastlog.h>
 
127
# endif
 
128
# include       <pwd.h>
 
129
#endif
 
130
 
 
131
#if defined(__SVR4) || defined(SVR4) || defined(linux) || defined(__GLIBC__)
 
132
#define SYSV
 
133
#endif
 
134
 
 
135
#ifdef CSRG_BASED
 
136
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
 
137
/* *BSD doesn't like a ':0' type entry in utmp */
 
138
#define NO_UTMP
 
139
#endif
 
140
#endif
 
141
 
 
142
#ifndef WTMP_FILE
 
143
# ifdef _PATH_WTMP
 
144
#  define WTMP_FILE     _PATH_WTMP
 
145
# else
 
146
#  define WTMP_FILE     "/usr/adm/wtmp"
 
147
# endif
 
148
#endif
 
149
#ifndef UTMP_FILE
 
150
# ifdef _PATH_UTMP
 
151
#  define UTMP_FILE     _PATH_UTMP
 
152
# else
 
153
#  define UTMP_FILE     "/etc/utmp"
 
154
# endif
 
155
#endif
 
156
#ifndef NO_LASTLOG
 
157
# ifndef LLOG_FILE
 
158
#  ifdef _PATH_LASTLOG
 
159
#   define LLOG_FILE    _PATH_LASTLOG
 
160
#  else
 
161
#   define LLOG_FILE    "/usr/adm/lastlog"
 
162
#  endif
 
163
# endif
 
164
#endif
 
165
#ifndef SYSV
 
166
# ifndef TTYS_FILE
 
167
#  define TTYS_FILE     "/etc/ttys"
 
168
# endif
 
169
#endif
 
170
 
 
171
#include <time.h>
 
172
#define Time_t time_t
 
173
#ifdef X_NOT_POSIX
 
174
extern long     lseek ();
 
175
extern char     *ttyname ();
 
176
#endif
 
177
 
 
178
static void set_utmp (struct utmp *u, char *line, char *user, char *host, Time_t date, int addp);
 
179
 
 
180
#ifdef USE_UTMPX
 
181
static void set_utmpx (struct utmpx *u, const char *line, const char *user,
 
182
                       const char *host, Time_t date, int addp);
 
183
#endif
 
184
 
 
185
int     wflag, uflag, lflag;
 
186
char    *wtmp_file, *utmp_file, *line;
 
187
#ifdef USE_UTMPX
 
188
static char *wtmpx_file = NULL, *utmpx_file = NULL;
 
189
#endif
 
190
int     utmp_none, wtmp_none;
 
191
/*
 
192
 * BSD specific variables.  To make life much easier for Xstartup/Xreset
 
193
 * maintainers, these arguments are accepted but ignored for sysV
 
194
 */
 
195
int     hflag, sflag, xflag, tflag;
 
196
char    *host_name = NULL;
 
197
int     slot_number;
 
198
char    *xservers_file, *ttys_file;
 
199
char    *user_name;
 
200
int     aflag, dflag;
 
201
#ifndef NO_LASTLOG
 
202
char    *llog_file;
 
203
int     llog_none, Lflag;
 
204
#endif
 
205
 
 
206
char    *program_name;
 
207
 
 
208
#ifndef SYSV
 
209
static int findslot (char *line_name, char *host_name, int addp, int slot);
 
210
static int Xslot (char *ttys_file, char *servers_file, char *tty_line,
 
211
                  char *host_name, int addp);
 
212
#endif
 
213
 
 
214
static int
 
215
usage (int x)
 
216
{
 
217
        if (x) {
 
218
                fprintf (stderr, "%s: usage %s {-a -d} [-w wtmp-file] [-u utmp-file]", program_name, program_name);
 
219
#ifndef NO_LASTLOG
 
220
                fprintf (stderr, " [-L lastlog-file]");
 
221
#endif
 
222
                fprintf (stderr, "\n");
 
223
                fprintf (stderr, "             [-t ttys-file] [-l line-name] [-h host-name]\n");
 
224
                fprintf (stderr, "             [-s slot-number] [-x servers-file] user-name\n");
 
225
                exit (1);
 
226
        }
 
227
        return x;
 
228
}
 
229
 
 
230
static char *
 
231
getstring (char ***avp, int *flagp)
 
232
{
 
233
        char    **a = *avp;
 
234
 
 
235
        usage ((*flagp)++);
 
236
        if (*++*a)
 
237
                return *a;
 
238
        ++a;
 
239
        usage (!*a);
 
240
        *avp = a;
 
241
        return *a;
 
242
}
 
243
 
 
244
#ifndef SYSV
 
245
static int
 
246
syserr (int x, const char *s)
 
247
{
 
248
        if (x == -1) {
 
249
                perror (s);
 
250
                exit (1);
 
251
        }
 
252
        return x;
 
253
}
 
254
#endif
 
255
 
 
256
static int
 
257
sysnerr (int x, const char *s)
 
258
{
 
259
        if (x == 0) {
 
260
                perror (s);
 
261
                exit (1);
 
262
        }
 
263
        return x;
 
264
}
 
265
 
 
266
int
 
267
main (int argc, char **argv)
 
268
{
 
269
#ifndef SYSV
 
270
        int             utmp;
 
271
#endif
 
272
        char            *line_tmp;
 
273
        int             wtmp;
 
274
        Time_t          current_time;
 
275
        struct utmp     utmp_entry;
 
276
#ifdef USE_UTMPX
 
277
        int             wtmpx;  
 
278
        struct utmpx    utmpx_entry;
 
279
#endif
 
280
 
 
281
        program_name = argv[0];
 
282
        while (*++argv && **argv == '-') {
 
283
                switch (*++*argv) {
 
284
                case 'w':
 
285
                        wtmp_file = getstring (&argv, &wflag);
 
286
                        if (!strcmp (wtmp_file, "none"))
 
287
                                wtmp_none = 1;
 
288
                        break;
 
289
                case 'u':
 
290
                        utmp_file = getstring (&argv, &uflag);
 
291
                        if (!strcmp (utmp_file, "none"))
 
292
                                utmp_none = 1;
 
293
                        break;
 
294
#ifndef NO_LASTLOG
 
295
                case 'L':
 
296
                        llog_file = getstring (&argv, &Lflag);
 
297
                        if (!strcmp (llog_file, "none"))
 
298
                                llog_none = 1;
 
299
                        break;
 
300
#endif
 
301
                case 't':
 
302
                        ttys_file = getstring (&argv, &tflag);
 
303
                        break;
 
304
                case 'l':
 
305
                        line = getstring (&argv, &lflag);
 
306
                        break;
 
307
                case 'h':
 
308
                        host_name = getstring (&argv, &hflag);
 
309
                        break;
 
310
                case 's':
 
311
                        slot_number = atoi (getstring (&argv, &sflag));
 
312
                        break;
 
313
                case 'x':
 
314
                        xservers_file = getstring (&argv, &xflag);
 
315
                        break;
 
316
                case 'a':
 
317
                        aflag++;
 
318
                        break;
 
319
                case 'd':
 
320
                        dflag++;
 
321
                        break;
 
322
                default:
 
323
                        usage (1);
 
324
                }
 
325
        }
 
326
        usage (!(user_name = *argv++));
 
327
        usage (*argv != 0);
 
328
        /*
 
329
         * complain if neither aflag nor dflag are set,
 
330
         * or if both are set.
 
331
         */
 
332
        usage (!(aflag ^ dflag));
 
333
        usage (xflag && !lflag);
 
334
        /* set up default file names */
 
335
        if (!wflag) {
 
336
                wtmp_file = WTMP_FILE;
 
337
#ifdef USE_UTMPX
 
338
                wtmpx_file = WTMPX_FILE;
 
339
#endif
 
340
        }
 
341
#ifndef NO_UTMP
 
342
        if (!uflag) {
 
343
                utmp_file = UTMP_FILE;
 
344
#ifdef USE_UTMPX
 
345
                utmpx_file = UTMPX_FILE;
 
346
#endif
 
347
        }
 
348
#else
 
349
        utmp_none = 1;
 
350
#endif
 
351
#ifndef NO_LASTLOG
 
352
        if (!Lflag)
 
353
                llog_file = LLOG_FILE;
 
354
#endif
 
355
#if !defined(SYSV) && !defined(linux) && !defined(__QNX__)
 
356
        if (!tflag)
 
357
                ttys_file = TTYS_FILE;
 
358
        if (!sflag && !utmp_none) {
 
359
                if (xflag)
 
360
                        sysnerr (slot_number = Xslot (ttys_file, xservers_file, line, host_name, aflag), "Xslot");
 
361
                else
 
362
                        sysnerr (slot_number = ttyslot (), "ttyslot");
 
363
        }
 
364
#endif
 
365
        if (!lflag) {
 
366
                sysnerr ((line_tmp = ttyname (0)) != NULL, "ttyname");
 
367
                line = strrchr(line_tmp, '/');
 
368
                if (line)
 
369
                        line = line + 1;
 
370
                else
 
371
                        line = line_tmp;
 
372
        }
 
373
        time (&current_time);
 
374
        set_utmp (&utmp_entry, line, user_name, host_name, current_time, aflag);
 
375
 
 
376
#ifdef USE_UTMPX
 
377
        /* need to set utmpxname() before calling set_utmpx() for
 
378
           UtmpxIdOpen to work */
 
379
        if (utmpx_file != NULL) {
 
380
                utmpxname (utmpx_file);
 
381
        }
 
382
        set_utmpx (&utmpx_entry, line, user_name,
 
383
                   host_name, current_time, aflag);
 
384
#endif  
 
385
 
 
386
        if (!utmp_none) {
 
387
#ifdef USE_UTMPX
 
388
            if (utmpx_file != NULL) {
 
389
                setutxent ();
 
390
                (void) getutxid (&utmpx_entry);
 
391
                pututxline (&utmpx_entry);
 
392
                endutxent ();
 
393
            }
 
394
#endif
 
395
#ifdef SYSV
 
396
                utmpname (utmp_file);
 
397
                setutent ();
 
398
                (void) getutid (&utmp_entry);
 
399
                pututline (&utmp_entry);
 
400
                endutent ();
 
401
#else
 
402
                utmp = open (utmp_file, O_RDWR);
 
403
                if (utmp != -1) {
 
404
                        syserr ((int) lseek (utmp, (long) slot_number * sizeof (struct utmp), 0), "lseek");
 
405
                        sysnerr (write (utmp, (char *) &utmp_entry, sizeof (utmp_entry))
 
406
                                        == sizeof (utmp_entry), "write utmp entry");
 
407
                        close (utmp);
 
408
                }
 
409
#endif
 
410
        }
 
411
        if (!wtmp_none) {
 
412
#ifdef USE_UTMPX
 
413
                if (wtmpx_file != NULL) {
 
414
                        updwtmpx(wtmpx_file, &utmpx_entry);
 
415
                }
 
416
#else
 
417
                wtmp = open (wtmp_file, O_WRONLY|O_APPEND);
 
418
                if (wtmp != -1) {
 
419
                        sysnerr (write (wtmp, (char *) &utmp_entry, sizeof (utmp_entry))
 
420
                                        == sizeof (utmp_entry), "write wtmp entry");
 
421
                        close (wtmp);
 
422
                }
 
423
#endif          
 
424
        }
 
425
#ifndef NO_LASTLOG
 
426
        if (aflag && !llog_none) {
 
427
                int llog;
 
428
                struct passwd *pwd = getpwnam(user_name);
 
429
 
 
430
                sysnerr( pwd != NULL, "get user id");
 
431
                llog = open (llog_file, O_RDWR);
 
432
 
 
433
                if (llog != -1) {
 
434
                        struct lastlog ll;
 
435
 
 
436
                        sysnerr (lseek(llog, (long) pwd->pw_uid*sizeof(ll), 0)
 
437
                                        != -1, "seeking lastlog entry");
 
438
                        bzero((char *)&ll, sizeof(ll));
 
439
                        ll.ll_time = current_time;
 
440
                        if (line)
 
441
                         (void) strncpy (ll.ll_line, line, sizeof (ll.ll_line));
 
442
                        if (host_name)
 
443
                         (void) strncpy (ll.ll_host, host_name, sizeof (ll.ll_host));
 
444
 
 
445
                        sysnerr (write (llog, (char *) &ll, sizeof (ll))
 
446
                                        == sizeof (ll), "write lastlog entry");
 
447
                        close (llog);
 
448
                }
 
449
        }
 
450
#endif
 
451
        return 0;
 
452
}
 
453
 
 
454
/*
 
455
 * fill in the appropriate records of the utmp entry
 
456
 */
 
457
 
 
458
static void
 
459
set_utmp (struct utmp *u, char *line, char *user, char *host, Time_t date, int addp)
 
460
{
 
461
        bzero (u, sizeof (*u));
 
462
        if (line)
 
463
                (void) strncpy (u->ut_line, line, sizeof (u->ut_line));
 
464
        else
 
465
                bzero (u->ut_line, sizeof (u->ut_line));
 
466
        if (addp && user)
 
467
                (void) strncpy (u->ut_name, user, sizeof (u->ut_name));
 
468
        else
 
469
                bzero (u->ut_name, sizeof (u->ut_name));
 
470
#ifdef SYSV
 
471
        if (line) {
 
472
                int     i;
 
473
                /*
 
474
                 * this is a bit crufty, but
 
475
                 * follows the apparent conventions in
 
476
                 * the ttys file.  ut_id is only 4 bytes
 
477
                 * long, and the last 4 bytes of the line
 
478
                 * name are written into it, left justified.
 
479
                 */
 
480
                i = strlen (line);
 
481
                if (i >= sizeof (u->ut_id))
 
482
                        i -= sizeof (u->ut_id);
 
483
                else
 
484
                        i = 0;
 
485
                (void) strncpy (u->ut_id, line + i, sizeof (u->ut_id));
 
486
        } else
 
487
                bzero (u->ut_id, sizeof (u->ut_id));
 
488
        if (addp) {
 
489
                u->ut_pid = getppid ();
 
490
                u->ut_type = USER_PROCESS;
 
491
        } else {
 
492
                u->ut_pid = 0;
 
493
                u->ut_type = DEAD_PROCESS;
 
494
        }
 
495
#endif
 
496
#if (!defined(SYSV) && !defined(__QNX__)) || defined(linux)
 
497
        if (addp && host)
 
498
                (void) strncpy (u->ut_host, host, sizeof (u->ut_host));
 
499
        else
 
500
                bzero (u->ut_host, sizeof (u->ut_host));
 
501
#endif
 
502
        u->ut_time = date;
 
503
}
 
504
 
 
505
#ifdef USE_UTMPX
 
506
static int
 
507
UtmpxIdOpen( char *utmpId )
 
508
{
 
509
        struct utmpx *u;        /* pointer to entry in utmp file           */
 
510
        int    status = 1;      /* return code                             */
 
511
 
 
512
        while ( (u = getutxent()) != NULL ) {
 
513
                
 
514
                if ( (strncmp(u->ut_id, utmpId, 4) == 0 ) &&
 
515
                     u->ut_type != DEAD_PROCESS ) {
 
516
                        
 
517
                        status = 0;
 
518
                        break;
 
519
                }
 
520
        }
 
521
 
 
522
        endutent();
 
523
        return (status);
 
524
}
 
525
 
 
526
static void
 
527
set_utmpx (struct utmpx *u, const char *line, const char *user,
 
528
           const char *host, Time_t date, int addp)
 
529
{
 
530
        static const char letters[] =
 
531
               "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
532
 
 
533
        if (line)
 
534
        {
 
535
                if(strcmp(line, ":0") == 0)
 
536
                        (void) strcpy(u->ut_line, "console");
 
537
                else
 
538
                        (void) strncpy (u->ut_line, line, sizeof (u->ut_line));
 
539
 
 
540
                strncpy(u->ut_host, line, sizeof(u->ut_host));
 
541
                u->ut_syslen = strlen(line); 
 
542
        }
 
543
        else
 
544
                bzero (u->ut_line, sizeof (u->ut_line));
 
545
        if (addp && user)
 
546
                (void) strncpy (u->ut_name, user, sizeof (u->ut_name));
 
547
        else
 
548
                bzero (u->ut_name, sizeof (u->ut_name));
 
549
 
 
550
        if (line) {
 
551
                int     i;
 
552
                /*
 
553
                 * this is a bit crufty, but
 
554
                 * follows the apparent conventions in
 
555
                 * the ttys file.  ut_id is only 4 bytes
 
556
                 * long, and the last 4 bytes of the line
 
557
                 * name are written into it, left justified.
 
558
                 */
 
559
                i = strlen (line);
 
560
                if (i >= sizeof (u->ut_id))
 
561
                        i -= sizeof (u->ut_id);
 
562
                else
 
563
                        i = 0;
 
564
                (void) strncpy (u->ut_id, line + i, sizeof (u->ut_id));
 
565
 
 
566
                /* make sure there is no entry using identical ut_id */
 
567
                if (!UtmpxIdOpen(u->ut_id) && addp) {
 
568
                        int limit = sizeof(letters) - 1;
 
569
                        int t = 0;
 
570
 
 
571
                        u->ut_id[1] = line[i];
 
572
                        u->ut_id[2] = line[i+1];
 
573
                        u->ut_id[3] = line[i+2];
 
574
                        do {
 
575
                                u->ut_id[0] = letters[t];
 
576
                                t++;
 
577
                        } while (!UtmpxIdOpen(u->ut_id) && (t < limit));
 
578
                }
 
579
                if (!addp && strstr(line, ":") != NULL) {
 
580
                        struct utmpx *tmpu;             
 
581
 
 
582
                        while ( (tmpu = getutxent()) != NULL ) {
 
583
                                if ( (strcmp(tmpu->ut_host, line) == 0 ) &&
 
584
                                        tmpu->ut_type != DEAD_PROCESS ) {
 
585
                                        strncpy(u->ut_id, tmpu->ut_id,
 
586
                                                sizeof(u->ut_id));
 
587
                                        break;
 
588
                                }
 
589
                        }
 
590
                        endutxent();
 
591
                }
 
592
        } else
 
593
                bzero (u->ut_id, sizeof (u->ut_id));
 
594
        
 
595
        if (addp) {
 
596
                u->ut_pid = getppid ();
 
597
                u->ut_type = USER_PROCESS;
 
598
        } else {
 
599
                u->ut_pid = 0;
 
600
                u->ut_type = DEAD_PROCESS;
 
601
        }
 
602
        u->ut_tv.tv_sec = date;
 
603
        u->ut_tv.tv_usec = 0;
 
604
}
 
605
#endif /* USE_UTMPX */
 
606
 
 
607
#ifndef SYSV
 
608
/*
 
609
 * compute the slot-number for an X display.  This is computed
 
610
 * by counting the lines in /etc/ttys and adding the line-number
 
611
 * that the display appears on in Xservers.  This is a poor
 
612
 * design, but is limited by the non-existant interface to utmp.
 
613
 * If host_name is non-NULL, assume it contains the display name,
 
614
 * otherwise use the tty_line argument (i.e., the tty name).
 
615
 */
 
616
 
 
617
static int
 
618
Xslot (char *ttys_file, char *servers_file, char *tty_line, char *host_name,
 
619
       int addp)
 
620
{
 
621
        FILE    *ttys, *servers;
 
622
        int     c;
 
623
        int     slot = 1;
 
624
        int     column0 = 1;
 
625
        char    servers_line[1024];
 
626
        char    disp_name[512];
 
627
        int     len;
 
628
        char    *pos;
 
629
 
 
630
        /* remove screen number from the display name */
 
631
        memset(disp_name, 0, sizeof(disp_name));
 
632
        strncpy(disp_name, host_name ? host_name : tty_line, sizeof(disp_name)-1);
 
633
        pos = strrchr(disp_name, ':');
 
634
        if (pos) {
 
635
            pos = strchr(pos, '.');
 
636
            if (pos)
 
637
                *pos = '\0';
 
638
        }
 
639
        sysnerr ((int)(long)(ttys = fopen (ttys_file, "r")), ttys_file);
 
640
        while ((c = getc (ttys)) != EOF)
 
641
                if (c == '\n') {
 
642
                        ++slot;
 
643
                        column0 = 1;
 
644
                } else
 
645
                        column0 = 0;
 
646
        if (!column0)
 
647
                ++slot;
 
648
        (void) fclose (ttys);
 
649
        sysnerr ((int)(long)(servers = fopen (servers_file, "r")), servers_file);
 
650
 
 
651
        len = strlen (disp_name);
 
652
        column0 = 1;
 
653
        while (fgets (servers_line, sizeof (servers_line), servers)) {
 
654
                if (column0 && *servers_line != '#') {
 
655
                        if (!strncmp (disp_name, servers_line, len) &&
 
656
                            (servers_line[len] == ' ' ||
 
657
                             servers_line[len] == '\t'))
 
658
                                return slot;
 
659
                        ++slot;
 
660
                }
 
661
                if (servers_line[strlen(servers_line)-1] != '\n')
 
662
                        column0 = 0;
 
663
                else
 
664
                        column0 = 1;
 
665
        }
 
666
        /*
 
667
         * display not found in Xservers file - allocate utmp entry dinamically
 
668
         */
 
669
        return findslot (tty_line, host_name, addp, slot);
 
670
}
 
671
 
 
672
/*
 
673
 * find a free utmp slot for the X display.  This allocates a new entry
 
674
 * past the regular tty entries if necessary, reusing existing entries
 
675
 * (identified by (line,hostname)) if possible.
 
676
 */
 
677
static int
 
678
findslot (char *line_name, char *host_name, int addp, int slot)
 
679
{
 
680
        int     utmp;
 
681
        struct  utmp entry;
 
682
        int     found = 0;
 
683
        int     freeslot = -1;
 
684
 
 
685
        syserr(utmp = open (utmp_file, O_RDONLY), "open utmp");
 
686
 
 
687
        /*
 
688
         * first, try to locate a previous entry for this display
 
689
         * also record location of a free slots in case we need a new one
 
690
         */
 
691
        syserr ((int) lseek (utmp, (long) slot * sizeof (struct utmp), 0), "lseek");
 
692
 
 
693
        if (!host_name)
 
694
                host_name = "";
 
695
 
 
696
        while (read (utmp, (char *) &entry, sizeof (entry)) == sizeof (entry)) {
 
697
                if (strncmp(entry.ut_line, line_name,
 
698
                        sizeof(entry.ut_line)) == 0 
 
699
#ifndef __QNX__
 
700
                    &&
 
701
                    strncmp(entry.ut_host, host_name,
 
702
                        sizeof(entry.ut_host)) == 0
 
703
#endif
 
704
                   ) {
 
705
                        found = 1;
 
706
                        break;
 
707
                }
 
708
                if (freeslot < 0 && *entry.ut_name == '\0')
 
709
                        freeslot = slot;
 
710
                ++slot;
 
711
        }
 
712
 
 
713
        close (utmp);
 
714
 
 
715
        if (found)
 
716
                return slot;
 
717
        else if (!addp)
 
718
                return 0;       /* trying to delete a non-existing entry */
 
719
        else if (freeslot < 0)
 
720
                return slot;    /* first slot past current entries */
 
721
        else
 
722
                return freeslot;
 
723
}
 
724
#endif