You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
qps-packaging/src/ttystr.cpp

212 lines
5.1 KiB

// ttystr.C
//
// This program is free software. See the file COPYING for details.
// Author: Mattias Engdegård, 1997-1999
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h> //major() minor()
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <dirent.h>
#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<int, char *> 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