Logo Search packages:      
Sourcecode: kdeadmin-kde4 version File versions  Download package

Disks.cc

/* Disks.cc
**
** Copyright (C) 2000,2001 by Bernhard Rosenkraenzer
**
** Contributions by A. Seigo and W. Bastian.
**
*/

/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program in a file called COPYING; if not, write to
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
** MA 02110-1301, USA.
*/

/*
** Bug reports and questions can be sent to <kde-devel@kde.org>
*/

#include "Disks.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>

StringList ptable::disklist()
{
      /* The basics behind scanning for a disk are simple: If it can be     *
       * opened, it exists.                                                 *
       * Using access() is not sufficient - that's successful if the device *
       * node exists but there's no actual device.                          *
       * Checking /proc/devices would work, but it wouldn't autoload modules*
       * so chances are we'd be missing something.                          */
      StringList dsk;
      int fd;
      bool finished=false;
      #define CHECK_DEV(d)    if((fd=open(d, O_RDONLY))<0) { \
                              finished=true; \
                              continue; \
                        } \
                        close(fd); \
                        dsk+=d
      String dev="/dev/hd";   // IDE devices: /dev/hd[a-t]
      for(char a='a'; a<='t'; a++) {
            // We can't use finished for IDE drives - it's perfectly OK
            // to have a /dev/hdc but no /dev/hdb.
            CHECK_DEV(dev+a);
      }
      finished=false;
      dev="/dev/sd";          // SCSI disks 0-25
      for(char a='a'; a<='z' && !finished; a++) {
            CHECK_DEV(dev+a);
      }
      for(char prefix='a'; prefix <='d' && !finished; prefix++) {
            dev="/dev/sd" + prefix; // SCSI disks 26-127
            for(char a='a'; (a<='x' || (a<='z' && prefix<'d')) && !finished; a++) {
                  CHECK_DEV(dev+a);
            }
      }
      finished=false;
      dev="/dev/i2o/hd";      // I2O disks 0-25: /dev/i2o/hd[a-z]
      for(char a='a'; a<='z' && !finished; a++) {
            CHECK_DEV(dev+a);
      }
      for(char prefix='a'; prefix <='d' && !finished; prefix++) {
            dev="/dev/i2o/hd" + prefix; // I2O disks 26-127
            for(char a='a'; (a<='x' || (a<='z' && prefix<'d')) && !finished; a++) {
                  CHECK_DEV(dev+a);
            }
      }
      finished=false;
      dev="/dev/pd";          // Parallel port disks: /dev/pd[a-d]
      for(char a='a'; a<='d' && !finished; a++) {
            CHECK_DEV(dev+a);
      }
      finished=false;
      for(unsigned int i=0; i<=31 && !finished; i++) { // Software RAID
            String device;
            device.sprintf("/dev/md%u", i);
            CHECK_DEV(device);
      }
      finished=false;
      for(unsigned int i=0; i<=7; i++) { //Compaq Smart Array
            for(unsigned int j=0; j<=15 && !finished; j++) {
                  String device;
                  device.sprintf("/dev/ida/c%ud%u", i, j);
                  CHECK_DEV(device);
            }
      }
      finished=false;
      for(unsigned int i=0; i<=7; i++) { // Mylex DAC960
            for(unsigned int j=0; j<=31 && !finished; j++) {
                  String device;
                  device.sprintf("/dev/rd/c%ud%u", i, j);
                  CHECK_DEV(device);
            }
      }
      finished=false;
      dev="/dev/ed";          // MCA ESDI harddisks: /dev/ed[ab]
      for(char a='a'; a<='b' && !finished; a++) {
            CHECK_DEV(dev+a);
      }
      finished=false;
      dev="/dev/xd";          // XT (8-bit) harddisks: /dev/xd[ab]
      for(char a='a'; a<='b' && !finished; a++) {
            CHECK_DEV(dev+a);
      }
      return dsk;
}
StringList ptable::partlist()
{
      StringList s;
      StringList d=disklist();
      for(StringList::const_iterator it=d.begin(); it!=d.end(); it++) {
            for(int i=1; i<32; i++) {
                  String drive;
                  drive.sprintf("%s%u", (*it).cstr(), i);
                  int fd=open(drive, O_RDONLY);
                  if(fd>=0) {
                        char test;
                        if(read(fd, &test, 1)>0)
                              s += drive;
                        close(fd);
                  } else
                        break;
            }
      }
      return s;
}
ptable::ptable(StringList const &disks)
{
      partition.clear();
      id.clear();
      mountpt.clear();
      for(StringList::const_iterator it=disks.begin(); it!=disks.end(); it++)
            scandisk(*it);
}
ptable::ptable(String const &disk)
{
      partition.clear();
      id.clear();
      mountpt.clear();
      scandisk(disk);
}
void ptable::scandisk(String const &disk)
{
      String cmd;
      cmd.sprintf("fdisk -l %s 2>&1", (char*)disk);
      FILE *fdisk=popen(cmd, "r");
      char *buf=(char *) malloc(1024);
      String dev;
      while(fgets(buf, 1024, fdisk)) {
            if(strncmp("/dev/", buf, 5)==0) { // Partition entry
                  // We don't care about active vs. non-active partitions.
                  // Remove the sign.
                  while(strchr(buf, '*')) *strchr(buf, '*')=' ';
                  // blanks are blanks...
                  while(strchr(buf, '\t')) *strchr(buf, '\t')=' ';
                  // Get the device
                  *strchr(buf, ' ')=0;
                  dev=buf;
                  partition += buf;
                  // And figure out where/if it's mounted
                  mountpt[dev]=mountpoint(dev);
                  // Lastly, get the partition type.
                  strcpy(buf, buf+strlen(buf)+1);
                  while(isspace(*buf)) strcpy(buf, buf+1);
                  strcpy(buf, strchr(buf, ' ')); // skip Start
                  while(isspace(*buf)) strcpy(buf, buf+1);
                  strcpy(buf, strchr(buf, ' ')); // skip End
                  while(isspace(*buf)) strcpy(buf, buf+1);
                  strcpy(buf, strchr(buf, ' ')); // skip Blocks
                  while(isspace(*buf)) strcpy(buf, buf+1);
                  id[dev]=strtol(buf, NULL, 16);
            }
      }
      pclose(fdisk);
      free(buf);
}
String ptable::mountpoint(String const &device, bool fstab_fallback)
{
      char *buf=new char[1024];
      FILE *f=fopen("/etc/mtab", "r");
      String mp="";
      while(fgets(buf, 1024, f)) {
            if(strchr(buf,' '))
                  *strchr(buf, ' ')=0;
            if(strchr(buf,'\t'))
                  *strchr(buf, '\t')=0;
            if(device.cmp(buf)) {
                  strcpy(buf, buf+strlen(buf)+1);
                  while(isspace(*buf))
                        strcpy(buf, buf+1);
                  if(strchr(buf,' '))
                        *strchr(buf, ' ')=0;
                  if(strchr(buf,'\t'))
                        *strchr(buf, '\t')=0;
                  mp=buf;
                  mp=mp.simplifyWhiteSpace();
                  break;
            }
      }
      fclose(f);
      if(mp.empty() && fstab_fallback) {
            f=fopen("/etc/fstab", "r");
            while(fgets(buf, 1024, f)) {
                  if(strchr(buf,' '))
                        *strchr(buf, ' ')=0;
                  if(strchr(buf,'\t'))
                        *strchr(buf, '\t')=0;
                  if(device.cmp(buf)) {
                        strcpy(buf, buf+strlen(buf)+1);
                        while(isspace(*buf))
                              strcpy(buf, buf+1);
                        if(strchr(buf,' '))
                              *strchr(buf, ' ')=0;
                        if(strchr(buf,'\t'))
                              *strchr(buf, '\t')=0;
                        mp=buf;
                        mp=mp.simplifyWhiteSpace();
                        break;
                  }
            }
            fclose(f);
      }
      delete buf;
      return mp;
}
String ptable::device(String const &mountpt, bool fstab_fallback)
{
      char *buf=new char[1024];
      FILE *f=fopen("/etc/mtab", "r");
      String dev="";
      while(fgets(buf, 1024, f)) {
            if(strchr(buf,' '))
                  *strchr(buf, ' ')=0;
            if(strchr(buf,'\t'))
                  *strchr(buf, '\t')=0;
            String device=buf;
            strcpy(buf, buf+strlen(buf)+1);
            while(isspace(*buf))
                  strcpy(buf, buf+1);
            if(strchr(buf,' '))
                  *strchr(buf, ' ')=0;
            if(strchr(buf,'\t'))
                  *strchr(buf, '\t')=0;
            String mp=buf;
            mp=mp.simplifyWhiteSpace();
            if(mp==mountpt) {
                  dev=device;
                  break;
            }
      }
      fclose(f);

      if(dev.empty() && fstab_fallback) {
            // The FS is not mounted - maybe it could be, though.
            f=fopen("/etc/fstab", "r");
            while(fgets(buf, 1024, f)) {
                  if(strchr(buf,' '))
                        *strchr(buf, ' ')=0;
                  if(strchr(buf,'\t'))
                        *strchr(buf, '\t')=0;
                  String device=buf;
                  strcpy(buf, buf+strlen(buf)+1);
                  while(isspace(*buf))
                        strcpy(buf, buf+1);
                  if(strchr(buf,' '))
                        *strchr(buf, ' ')=0;
                  if(strchr(buf,'\t'))
                        *strchr(buf, '\t')=0;
                  String mp=buf;
                  mp=mp.simplifyWhiteSpace();
                  if(mp==mountpt) {
                        dev=device;
                        break;
                  }
            }
            fclose(f);
      }
      delete buf;
      return dev;
}

Generated by  Doxygen 1.6.0   Back to index