--- acct-6.3.2/dev_hash.c.pts Thu Apr 18 19:18:15 1996 +++ acct-6.3.2/dev_hash.c Tue Aug 31 17:20:56 2004 @@ -29,6 +29,7 @@ #include #include +#include #include #include "common.h" @@ -52,6 +53,11 @@ # endif #endif +#ifdef __linux__ +#define NULLDEV 0 +#else +#define NULLDEV -1 +#endif /* globals */ @@ -62,6 +68,55 @@ }; +/* hash all possible /dev/pts devices as they only appear + * in the filesystem when the device is active. + */ + +static void +setup_pts_devices () { + + struct utsname uts; + struct dev_data dd; + int i; + struct pts_params { + char *utsname; /* os name */ + int base; /* base major number */ + int max; /* max # of devices */ + int mod; /* number of minors per major */ + } *pts_ent, pts_table[] = { + {"Linux", 136, 2048, 256}, + { } + }; + + if( uname (&uts) ) { + /* silent error */ + return; + } + + for (pts_ent = &(pts_table[0]); pts_ent != NULL; ++pts_ent) { + if (!strcmp (uts.sysname, pts_ent->utsname)) + break; + } + if (pts_ent == NULL) return; /* unsupported OS */ + + for (i = 0; i < pts_ent->max; ++i) { + long dev_num; + struct hashtab_elem *he; + int major, minor; + + major = pts_ent->base + (i/pts_ent->mod); + minor = i % pts_ent->mod; + dev_num = ((major << 8) + minor); + + dd.name = xmalloc (sizeof(char) * (strlen("pts/xxxx") + 1)); + sprintf (dd.name, "pts/%d", i); + + he = hashtab_create (dev_table, (void *) & dev_num, sizeof(dev_num)); + hashtab_set_value (he, &dd, sizeof (dd)); + } +} + + /* Read the DIRNAME directory entries and make a linked list of ttys (so we can search through it later) */ @@ -79,7 +134,14 @@ if ((dirp = opendir (dirname)) == NULL) return; /* skip it silently */ - + + if (!strcmp (dirname, "/dev/pts")) { + /* assuming SysV, these are dynamically allocated */ + closedir (dirp); + setup_pts_devices (); + return; + } + for (dp = readdir (dirp); dp != NULL; dp = readdir (dirp)) { char *fullname = (char *) alloca ((strlen (dirname) @@ -105,7 +167,7 @@ dev_num = sp.st_rdev; dd.name = (char *) xmalloc (sizeof (char) * (NAMLEN (dp) + 1)); strcpy (dd.name, dp->d_name); - + he = hashtab_create (dev_table, (void *) &dev_num, sizeof (dev_num)); hashtab_set_value (he, &dd, sizeof (dd)); } @@ -114,6 +176,8 @@ } + + /* Return the name of the device associated with DEV_NUM. The argument passed was originally a dev_t, but that data type is too limited on some systems (won't let us pass -1 because it's an @@ -123,10 +187,11 @@ devname (long dev_num) { struct hashtab_elem *he; + static char devstr [20]; /* special case */ - if (dev_num == -1) + if (dev_num == NULLDEV) return "__"; if (dev_table == NULL) @@ -135,6 +200,7 @@ setup_devices ("/dev"); /* most certainly */ setup_devices ("/dev/pty"); /* perhaps */ setup_devices ("/dev/ptym"); /* perhaps */ + setup_devices ("/dev/pts"); /* perhaps */ } he = hashtab_find (dev_table, (void *) &dev_num, sizeof (dev_num)); @@ -144,9 +210,12 @@ struct dev_data *dd = hashtab_get_value (he); return dd->name; } - - /* didn't find it */ - - return "??"; + + /* didn't find it, return it as [maj,min] */ + + sprintf (devstr, "[%d,%d]", /* is this portable? */ + (int) ((dev_num & 0xFF00) >> 8), (int) (dev_num & 0x00FF)); + + return devstr; }