Example #1
0
bool DevCheck::devInfo(QString dev, QString* type, QString* label, QString* filesystem, QString* maxsize){
  //OUTPUT: bool isGoodDevice
  //INPUTS/OUTPUTS: type, label, filesystem, maxsize
  //INPUT: dev = device node (da0, not /dev/da0)
	
  //Clear the output variables
  type->clear(); label->clear(); filesystem->clear(); maxsize->clear();
  //make sure to have both the full path and just node
  QString node;
  QString fullDev;
  if(dev.startsWith(DEVICEDIR)){ fullDev = dev; node = dev.section("/",-1); }
  else{ node = dev; fullDev = DEVICEDIR + dev; }
  //Do not allow sym-links
  if(!QFile::symLinkTarget(fullDev).isEmpty()){ return FALSE; }
  //Do not allow currently active devices
  if(activeDevs.contains(node)){ return FALSE; }
  //Double check for valid device types (just in case)
  QString detType;
  for(int i=0; i<validDevs.length(); i++){
    if(node.startsWith(validDevs[i]) && node != "mdctl"){ 
	detType = validDevTypes[i]; 
	break; 
    }
  }
  //Make sure it is a no-child device (except memory disks or CD's, those need to be the parent)
  int children = devChildren(node).length();
  if( !node.startsWith("md") && detType!="CD9660" && detType!="ISO" && children>0 ){ return FALSE; }
  //Make sure we quit before running commands on any invalid device nodes
  if(detType.isEmpty() || !QFile::exists(fullDev) ){return FALSE;}
  //Get the camctl info and refine the device type if possible
  QString camctl;
  if(detType == "USB" && QFile::exists(fullDev)){
    //make sure that it is not a SCSI device
    camctl = pcbsd::Utils::runShellCommand( QString("camcontrol inquiry ")+node.section("s",0,0) ).join(" ");
    if(camctl.contains(" Fixed Direct Access SCSI")){ detType = "SCSI"; }
    if(camctl.contains("camcontrol")){ camctl.clear(); } //error or invalid device type
  }else if(detType == "SATA" && QFile::exists(fullDev)){
    camctl = pcbsd::Utils::runShellCommand( QString("camcontrol identify ")+node.section("s",0,0) ).join(" ");
    if(camctl.contains("camcontrol")){ camctl.clear(); } //error or invalid device type
  }
  if(!camctl.isEmpty()){
    //Alternate Device name for label later (if needed)
    camctl = camctl.section(">",0,0).section("<",-1).section(" ",0,0).simplified();
    QString partition = node.section("s",1,1);
    if(!partition.isEmpty()){ camctl.append("-"+partition); }
  }
  //Save the device type
  type->append(detType);
  
  bool isCD= (detType == "CD9660" || detType == "ISO"); //simplification for later
  //Run either "file -s" or "disktype" to get device info
  bool valid = false;
  QString fs, dlabel;
  if(QFile::exists("/usr/local/bin/disktype")){
    valid = getDiskInfo(fullDev, &fs, &dlabel);
  }else{
    // "file -s" should always work - use it as the backup method
    valid = getSpecialFileInfo(fullDev, &fs, &dlabel);
  }
  if(detType=="ISO" && fs.isEmpty() ){ valid = false; } //skip ISO's with unknown filesystems (swap, etc)
  else if(detType=="CD9660" &&  fs.isEmpty() ){
    //Try to determine which type of cd/dvd this is since it is not a data disk (which can be mounted)
    fs = "AVDISK"; //audio/video disk (not mountable)
  }
  if(!valid){ //don't bother continuing - already invalid
    if(DEBUG_MODE){ qDebug() << "Invalid Device:" << node << detType << dlabel << fs; } 
    return FALSE; 
  } 
 
  //If the filesystem could not be detected or is not supported
  if(fs.isEmpty()){ fs = "UNKNOWN"; }
  
  //Now get the device label (if there is one) using glabel
  QString glabel;
  //Don't use glabel for SATA devices right now because it is inconsistent
  if(!isCD){ glabel = devLabel(node, fs); }
  //Check to see if we have a label, otherwise assign one
  if( !glabel.isEmpty() ){ dlabel = glabel; } //glabel
  else if(!dlabel.isEmpty()){ } //device info label
  else if( !camctl.isEmpty() ){ dlabel = camctl; } //camcontrol device ID
  else{
    //Assign a device label
    if(isCD){
      if(detType == "ISO"){
	dlabel = "ISO_File";
      }else{
        dlabel = "Optical_Disk";
      }
    }else{
      dlabel = detType+"-Device"; //this is not a "detected" label
    }
  }
  //make sure that a device label does not contain "(" or ")"
  if(dlabel.contains("(")){ dlabel = dlabel.remove("(").simplified(); }
  if(dlabel.contains(")")){ dlabel = dlabel.remove(")").simplified(); }
  dlabel = dlabel.simplified();

  //Setup the outputs
  label->append(dlabel);
  filesystem->append(fs);
  return valid;
}
Example #2
0
bool DevCheck::devInfo(QString dev, QString* type, QString* label, QString* filesystem, QString* maxsize){
  //OUTPUT: bool isGoodDevice
  //INPUTS/OUTPUTS: type, label, filesystem, maxsize
  //INPUT: dev = device node (da0, not /dev/da0)
	
  //Clear the output variables
  type->clear(); label->clear(); filesystem->clear(); maxsize->clear();
  //make sure to have both the full path and just node
  QString node;
  QString fullDev;
  if(dev.startsWith(DEVICEDIR)){ fullDev = dev; node = dev.section("/",-1); }
  else{ node = dev; fullDev = DEVICEDIR + dev; }
  //Do not allow sym-links
  if(!QFile::symLinkTarget(fullDev).isEmpty()){ return FALSE; }
  
  //Double check for valid device types (just in case)
  QString detType;
  for(int i=0; i<validDevs.length(); i++){
    if(node.startsWith(validDevs[i]) && node != "mdctl"){ 
	detType = validDevTypes[i]; 
	break; 
    }
  }
  QString camctl;
  if(detType == "USB" && QFile::exists(fullDev)){
    //make sure that it is not a SCSI device
    camctl = pcbsd::Utils::runShellCommand( QString("camcontrol inquiry ")+node ).join(" ");
    if(camctl.contains(" Fixed Direct Access SCSI")){ detType = "SCSI"; } //USB devices do not have any output
    if(camctl.contains("camcontrol")){ camctl.clear(); } //error or invalid device type
  }
  //Make sure we quit before running commands on any invalid device nodes
  if(detType.isEmpty() || !QFile::exists(fullDev) ){return FALSE;}
  else{type->append(detType);}
  bool isCD=FALSE;
  if(detType == "CD9660" || detType == "ISO"){ isCD=TRUE; }
  
  //Read the Device Info using "file -s <device>"
  QString cmd = "file -s "+fullDev;
  QString output = pcbsd::Utils::runShellCommand(cmd).join(" ");
  //if(isCD){ qDebug() << "File -s output:" << output; }
  
  // ** Get the max storage size **
  int kb = 0;
  bool hasPartitions = FALSE; 
  bool isMounted = FALSE;
  if( !isCD ){
    QStringList tmp = output.split(",");
    if( !tmp.filter("partition ").isEmpty() ){
      //Check for actual sub-devices (*s[#][a/b/c/....])
      if( devChildren(node).length() > 0 ){ hasPartitions = TRUE; }
    }
    if( !tmp.filter("last mounted on /").isEmpty() && (detType == "SATA")){
      isMounted = TRUE;
    }
    //Now try to get the size of the disk
    if( !tmp.filter("number of data blocks").isEmpty() ){
      tmp = tmp.filter("number of data blocks");
      kb = tmp[0].remove("number of data blocks").simplified().toInt();
    }else if( !tmp.filter("number of blocks").isEmpty() ){
      tmp = tmp.filter("number of blocks");
      kb = tmp[0].remove("number of blocks").simplified().toInt();
    }else if( !tmp.filter("hidden sectors").isEmpty()){
      tmp = tmp.filter("hidden sectors");
      kb = tmp[0].remove("hidden sectors").simplified().toInt();
    }else if( !tmp.filter("sectors").isEmpty()){
      tmp = tmp.filter("sectors");
      //qDebug() << "Det Sectors line:"<<tmp;
      int num=0;
      for(int i=0; i<tmp.length(); i++){
        int n = tmp[i].remove("sectors").section("(",0,0).simplified().toInt();
        if(n > num){ num = n; }
      }
      kb = num;
    }else{ kb = -1; }
  } //end non-CD size and isMounted detection
  bool oksize = (kb > 0);
  //First try to get the device label using the "file -s" output
  QString dlabel;
  if(isCD){
    if( !output.contains("ERROR:") ){
      dlabel = output.section("'",-2).remove("'").simplified();
      if(dlabel.contains("(")){ dlabel = dlabel.left(dlabel.indexOf("(")+1).trimmed();}
    }
  }else{
   dlabel = output.section("label: \"",1,1).section("\"",0,0).simplified(); //device name
  }
  // - trim the label out of the output line for filesystem type detection
  QString devFSsec, devFSsec2;
  if(!isCD){
    devFSsec = output.section("label:",0,0);
    devFSsec2 = output.section("label:",1,3).section(",",1,1,QString::SectionSkipEmpty);
  }else{
    devFSsec = output.simplified();	  
  }
  // ** Find the filesystem type for the device **
  QString filesys;
  for(int i=0; i<fsDetection.length(); i++){
    if(devFSsec.contains(fsDetection[i]) || devFSsec2.contains(fsDetection[i]) ){
      filesys = fsMatch[i]; 
    }
  }
  //If the filesystem could not be detected or is not supported
  bool hasFS = TRUE;
  if(filesys.isEmpty()){ filesys = "UNKNOWN"; hasFS=FALSE; }
  
  //Now get the device label (if there is one) using glabel
  bool hasLabel = FALSE;
  QString glabel;
  if(!isCD){ glabel = devLabel(node, filesys); }
  //Check to see if we have a label, otherwise assign one
  if( !glabel.isEmpty() ){ dlabel = glabel; hasLabel = TRUE; } //glabel
  else if(!dlabel.isEmpty()){ hasLabel = TRUE; } //file -s label
  else if( !camctl.isEmpty() ){ 
    //not necessarily a "detected" label, but just an alternate fallback name
    dlabel = camctl.section(">",0,0).section("<",-1).section(" ",0,0).simplified();
  }else{
    //Assign a device label
    if(isCD){
      if(detType == "ISO"){
	dlabel = "ISO_File";
      }else{
        dlabel = "Optical_Disk";
      }
    }else{
      dlabel = detType+"-Device"; //this is not a "detected" label
    }
  }
  //make sure that a device label does not contain "(" or ")"
  if(dlabel.contains("(")){ dlabel.remove("(").simplified(); }
  if(dlabel.contains(")")){ dlabel.remove(")").simplified(); }
  dlabel = dlabel.simplified();
  //Now perform the final checks to see if it is a good device
  bool good = FALSE;
  if( isMounted ){}//Always ignore this device (local FreeBSD installation that is being used)
  else if( hasPartitions ){} //Ignore devices that have partitions accessible as seperate devices
  else if( hasFS && isCD ){ good = TRUE; } //CD/DVD data disks don't have as much info
  //Allow devices that match 2 of the 3 criteria
  else if( hasFS && oksize ){ good = TRUE; } //This will catch most good devices
  else if( hasLabel && oksize ){ good = TRUE; } //allow unknown filesystems if there is a good size reading
  else if( hasFS && hasLabel ){ good = TRUE; } // allow device if it has a known label and filesystem
  
  //Now setup the outputs as appropriate
  maxsize->append( QString::number(kb) );
  label->append(dlabel);
  filesystem->append(filesys);
  
  if(!good){
    qDebug() << "Invalid Device:" << node << detType << dlabel << filesys << kb; 
    if(DEBUG_MODE){qDebug() << " -Detected Flags:" << isMounted << hasPartitions << hasLabel << hasFS << oksize;} 
  }
  return good;
}