File: getutent.c

package info (click to toggle)
orville-write 2.55-2.3
  • links: PTS
  • area: main
  • in suites: squeeze, wheezy
  • size: 568 kB
  • ctags: 317
  • sloc: ansic: 3,494; sh: 2,978; makefile: 156
file content (130 lines) | stat: -rw-r--r-- 2,434 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* GETUTENT ROUTINES FOR SYSTEMS THAT HAVEN'T GOT THEM */

#include "orville.h"

#ifndef HAVE_GETUTENT
#include <sys/stat.h>

static struct {
	char *fname;	/* Filename.  If NULL, name is _PATH_UTMP */
	int fd;		/* file descriptor for open utmp file */
	int state;	/* 0 = not open; 1 = open; -1 = cannot open */
	} utmp= {NULL,0,0};


/* OPENUTENT - Ensure the utmp file is open.  Return non-zero if it can't be
 * opened.  This routine is not exported.
 */

static int openut()
{
    if (utmp.state == 0)
    {
	if ((utmp.fd= open(utmp.fname ? utmp.fname : _PATH_UTMP,
		O_RDONLY)) < 0)
	{
	    utmp.state= -1;
	    return -1;
	}
	else
	{
	    utmp.state= 1;
	    fcntl(utmp.fd, F_SETFD, 1);		/* Close over execs */
	    return 0;
	}
    }
}


/* ENDUTENT - Close the utmp file.
 */

void endutent()
{
    if (utmp.state == 1)
    	close(utmp.fd);
    utmp.state= 0;
}


/* SETUTENT - Rewind the utmp file.
 */

void setutent()
{
    if (utmp.state == 1)
    	lseek(utmp.fd, 0L, 0);
}


/* UTMPNAME - Set the name of the utmp file.
 */

int utmpname(const char *file)
{
    /* Close any currently open file */
    endutent();

    if (utmp.fname != NULL) free(utmp.fname);
    utmp.fname= strdup(file);

    return 0;
}


/* GETUTENT - Read the next entry from the utmp file into static storage.
 */

struct utmp *getutent()
{
static struct utmp ut;

    switch (utmp.state)
    {
    case 0:
	openut();
    	/* Drop through */
    case 1:
	if (read(utmp.fd, &ut, sizeof(struct utmp)) == sizeof(struct utmp))
	    return &ut;
    	/* Drop through */
    default:
    	return (struct utmp *)NULL;
    }
}


/* GETUTLINE - Return utmp entry for the next entry in the utmp file whose
 * ut_line field matches in->ut_line.  It's obnoxious that this wants a
 * whole utmp structure passed in instead of just a char pointer, but
 * we conform with Linux and Solaris.
 */

struct utmp *getutline(const struct utmp *in)
{
static struct utmp ut;

    switch (utmp.state)
    {
    case 0:
	openut();
    	/* Drop through */
    case 1:
	while (read(utmp.fd, &ut, sizeof(struct utmp)) == sizeof(struct utmp))
	{
	    if (
#if defined(USER_PROCESS) && defined(LOGIN_PROCESS)
	        (ut.ut_type == USER_PROCESS || ut.ut_type == LOGIN_PROCESS) &&
#endif
		!strncmp(ut.ut_line, in->ut_line, UT_LINESIZE))
	    {
		return &ut;
	    }
    	}
    	/* Drop through */
    default:
    	return (struct utmp *)NULL;
    }
}

#endif /* HAVE_GETUTENT */