// ttystr.C // // This program is free software. See the file COPYING for details. // Author: Mattias Engdegård, 1997-1999 #include #include #include #include //major() minor() #include #include #include #include #include #include "ttystr.h" #ifdef LINUX // Table of various tty devices (mostly serial boards) struct Ttytab { short dev_maj; // major number of tty char prefix; char callout; // 1 if callout device, 0 if tty }; static Ttytab ttytab[] = {{19, 'C', 0}, // Cyclades {20, 'b', 1}, {22, 'D', 0}, // Digiboard {23, 'd', 1}, {24, 'E', 0}, // Stallion {25, 'e', 1}, {32, 'X', 0}, // Specialix {33, 'x', 1}, {46, 'R', 0}, // Comtrol Rocketport {47, 'r', 1}, {48, 'L', 0}, // SDL RISCom {49, 'l', 1}, {57, 'P', 0}, // Hayes ESP {58, 'p', 1}, {71, 'F', 0}, // Computone IntelliPort II {72, 'f', 1}, {75, 'W', 0}, // Specialix IO8+ {76, 'w', 1}, {78, 'M', 0}, // PAM Software's multimodem boards {79, 'm', 1}, {105, 'V', 0}, // Comtrol VS-1000 {106, 'v', 1}, {0, 0, 0}}; // Return tty name of a device. Remove leading "tty" if any. // Return "-" if devnr is zero, "?" if unknown. QString Ttystr::name(dev_t devnr) { if (devnr == 0) return "-"; int dmin = minor(devnr); int dmaj = major(devnr); char name[40]; switch (dmaj) { case 3: // BSD-style pty slaves name[0] = "pqrstuvwxyzabcde"[(dmin >> 4) & 0xf]; name[1] = "0123456789abcdef"[dmin & 0xf]; name[2] = '\0'; break; case 4: if (dmin < 64) { // virtual console 0..63 sprintf(name, "%d", dmin); } else if (dmin < 128) { // serial port 0..63 sprintf(name, "S%d", dmin - 64); } else if (dmin >= 192 && dmin < 256) { // obsolete tty devices name[0] = "pqrs"[(dmin >> 4) & 0x3]; name[1] = "0123456789abcdef"[dmin & 0xf]; name[2] = '\0'; } else strcpy(name, "?"); break; case 5: // alternate tty devices switch (dmin) { case 0: strcpy(name, "tty"); break; case 1: strcpy(name, "console"); break; case 2: strcpy(name, "ptmx"); break; default: if (dmin >= 64 && dmin < 128) { // callout devices 0..63 sprintf(name, "cua%d", dmin - 64); } else strcpy(name, "?"); } default: if (dmaj >= 136 && dmaj < 144) { // Unix98 pty slaves sprintf(name, "pts/%d", ((dmaj - 136) << 8) + dmin); break; } // Various serial tty devices for (int i = 0; ttytab[i].dev_maj; i++) { if (dmaj == ttytab[i].dev_maj) { sprintf(name, "%s%c%d", ttytab[i].callout ? "cu" : "", ttytab[i].prefix, dmin); break; } } strcpy(name, "?"); } return name; } #endif // LINUX #ifdef SOLARIS QHash Ttystr::dict; bool Ttystr::scanned = FALSE; // return tty name, '-' if no tty, "??" if unidentifiable tty QString Ttystr::name(dev_t devnr) { if (!scanned) { read_devs(); scanned = TRUE; // just scan /dev once } QString s; if (devnr == (dev_t)-1) s = "-"; else { char *ts = dict.value(devnr, NULL); if (ts) s = ts; else s = "??"; } return s; } // scan device directory or subdirectory thereof void Ttystr::scandevdir(const char *prefix) { char dirname[80] = "/dev"; strcat(dirname, prefix); DIR *d = opendir(dirname); if (!d) return; struct dirent *e; struct stat sb; char name[80]; while ((e = readdir(d)) != 0) { sprintf(name, "/dev%s/%s", prefix, e->d_name); if (stat(name, &sb) >= 0) { if (S_ISCHR(sb.st_mode)) { dev_t d = sb.st_rdev; if (!dict.value(d, NULL)) { dict.insert(sb.st_rdev, strdup(name + 5)); // skip "/dev/" } } } } closedir(d); } void Ttystr::read_devs() { // scan /dev and various subdirectories. In case of duplicates, pick // the first name encountered scandevdir("/term"); scandevdir(""); scandevdir("/pts"); scandevdir("/cua"); } #endif // SOLARIS