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.
212 lines
5.1 KiB
212 lines
5.1 KiB
// ttystr.cpp
|
|
//
|
|
// 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
|