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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206
|
/* Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <utmpx.h>
#include <pwd.h>
#define import_spp
#define import_alloc
#define import_kernel
#define import_knames
#include <iraf.h>
/*
* ZALLOC.C -- Device allocation interface. Requires the dev$devices table,
* which is read by the high level code before we are called.
*
* zdvall (device, allflg, status) allocate/deallocate device
* zdvown (device, owner, maxch, status) query device allocation
*
* Status returns (import_alloc):
*
* OK operation successful
* ERR cannot allocate device
* DV_DEVALLOC device is already allocated
* DV_DEVINUSE device is in use by someone else
* DV_DEVFREE device is free and can be allocated
*
* The DEVICE name is a list of aliases for the physical device. On UNIX there
* can be multiple elements in the list (e.g., for a tape drive), but on other
* systems there may never be more than one device name. The elements of the
* list are delimited by whitespace. On host systems that do not support
* multiple device aliases, the kernel may assume that DEVICE is a scalar.
*/
#define ALLOCEXE "alloc.e"
static int u_allocstat (char *aliases);
/* ZDVALL -- Allocate or deallocate a device. UNIX does not explicitly support
* device allocation, so we fake it by setting the device owner and removing
* group and other permissions. This requires superuser privilege, hence a
* separate process HLIB$ALLOC.E is used to set/remove device allocation.
*/
int
ZDVALL (
PKCHAR *aliases, /* list of aliases for device */
XINT *allflg, /* allocate or deallocate device? */
XINT *status /* receives status word */
)
{
PKCHAR cmd[SZ_LINE+1], nullstr[1];
extern int ZOSCMD (PKCHAR *oscmd, PKCHAR *stdin_file, PKCHAR *stdout_file, PKCHAR *stderr_file, XINT *status);
/* Syntax: $host/hlib/alloc.e -[ad] aliases
*/
strcpy ((char *)cmd, irafpath(ALLOCEXE));
strcat ((char *)cmd, *allflg ? " -a " : " -d ");
strcat ((char *)cmd, (char *)aliases);
*nullstr = XEOS;
(void) ZOSCMD (cmd, nullstr, nullstr, nullstr, status);
if (*status == DV_ERROR)
*status = XERR;
return (*status);
}
/* ZDVOWN -- Query device allocation. Tells whether or not the named device
* is allocated, and if so returns the "name" of the owner in the owner
* string. Just what the "name" string is is not precisely defined, it is
* merely printed for the user to tell them the status of the device.
* Note that the device is not considered to be allocated if the owner
* is not currently logged in.
*
* Device files may be specified by a full pathname, as a user directory
* relative pathname, or by the device name in /dev or /dev/rmt.
*/
int
ZDVOWN (
PKCHAR *device, /* device name (not a list) */
PKCHAR *owner, /* receives owner string */
XINT *maxch, /* max chars out */
XINT *status /* receives allocation status */
)
{
register int uid;
char *dev, devname[SZ_FNAME+1];
struct passwd *pw;
struct stat fi;
/* Get device pathname. */
dev = (char *)device;
if (dev[0] == '/') {
strcpy (devname, dev);
} else if (dev[0] == '~' && dev[1] == '/') {
/* User home directory relative pathname. */
struct passwd *pwd;
pwd = getpwuid (getuid());
if (pwd != NULL) {
strcpy (devname, pwd->pw_dir);
strcat (devname, &dev[1]);
endpwent();
}
} else {
sprintf (devname, "/dev/%s", dev);
if (access (devname, 0) == ERR)
sprintf (devname, "/dev/rmt/%s", dev);
}
if (stat (devname, &fi) == ERR) {
*status = XERR;
return (XERR);
}
uid = fi.st_uid;
*owner = XEOS;
if (uid == 0)
*status = DV_DEVFREE;
else if (uid == getuid())
*status = DV_DEVALLOC;
/* else if (!loggedin (uid)) */
else if (u_allocstat ((char *)device) == DV_DEVFREE)
*status = DV_DEVFREE;
else {
if ((pw = getpwuid (uid)) == NULL)
sprintf ((char *)owner, "%d", uid);
else
strncpy ((char *)owner, pw->pw_name, *maxch);
*status = DV_DEVINUSE;
}
return (*status);
}
/* LOGGEDIN -- Return 1 if uid is logged in, else 0.
*/
int
loggedin (int uid)
{
struct utmpx ubuf;
struct passwd *pw;
FILE *ufp;
if ((ufp = fopen ("/var/run/utmp", "r")) == NULL) {
printf ("zdvown: cannot open /var/run/utmp\n");
return (1);
}
if ((pw = getpwuid (uid)) == NULL) {
fclose (ufp);
return (0);
}
do {
if (fread (&ubuf, sizeof (struct utmpx), 1, ufp) == (size_t) 0) {
fclose (ufp);
return (0);
}
} while (strncmp (ubuf.ut_user, pw->pw_name, 8) != 0);
fclose (ufp);
return (1);
}
/* U_ALLOCSTAT -- Call alloc.e to get the device status. Currently, this has
* to be done by a priviledged process as the process table is used in some
* cases.
*/
static int
u_allocstat (
char *aliases /* list of aliases for device */
)
{
PKCHAR cmd[SZ_LINE+1], nullstr[1];
XINT x_status;
extern int ZOSCMD(PKCHAR *oscmd, PKCHAR *stdin_file, PKCHAR *stdout_file, PKCHAR *stderr_file, XINT *status);
/* Syntax: $host/hlib/alloc.e -s aliases
*/
strcpy ((char *)cmd, irafpath(ALLOCEXE));
strcat ((char *)cmd, " -s ");
strcat ((char *)cmd, aliases);
*nullstr = XEOS;
(void) ZOSCMD (cmd, nullstr, nullstr, nullstr, &x_status);
if (x_status == DV_ERROR)
x_status = XERR;
return (x_status);
}
|