Logo Search packages:      
Sourcecode: qps version File versions  Download package

ttystr.cpp

// 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>
#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

QIntDict<char> Ttystr::dict(69);
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[devnr];
      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[d]) {
                dict.insert(sb.st_rdev, strdup(name + 5)); // skip "/dev/"
                if(dict.count() > dict.size() * 3)
                  dict.resize(dict.count());
            }
          }
      }
    }
    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

Generated by  Doxygen 1.6.0   Back to index