LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 06-16-2005, 08:33 PM   #1
Chrax
Member
 
Registered: Apr 2004
Distribution: Dapper
Posts: 167

Rep: Reputation: 31
CD/DVD autodetection


I don't know if anybody saw my earlier post, but please disregard it.

Those programs were early attempts at CD auto-detection, and while they worked, they had unreasonable dependencies for such simple programs.

I've written another program entirely in C that detects all optical drives and their capabilities, and what's more, it's only dependency is that you run Linux. (If there are any *nix folks out there that are not running Linux, I'd be very interested in ioctl information. I simply only have access to Linux at this point.)

Code:
#include <stdio.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <linux/cdrom.h>

char **optical_drives;
int *capabilities;
int num_drives;

/* find_devs - Recursively find all optical devices */
int find_devs(char *base){
  DIR *base_dir;
  struct dirent *file;
  base_dir = opendir(base);
  while((file = readdir(base_dir)) != NULL){
    
    /* Ignore . and .. if readdir gives them to us */
    if(strcmp((*file).d_name, ".") == 0 || strcmp((*file).d_name, "..") == 0)
      continue;
    
    /* An extra two characters to account for the \0 and potentially a slash */
    char *file_name = malloc(strlen(base) + strlen((*file).d_name) + 2);
    strcpy(file_name,base);
    
    /* Make sure directory has a / after it before concatenating the file name */
    if(file_name[strlen(base) - 1] != '/')
      strcat(file_name,"/");
    
    strcat(file_name,(*file).d_name);
    
    /* For some reason, some symlinks act really oddly, so we're not going to
     * bother with them. Besides, this will keep us from getting duplicates.
     * I don't think devs can be hardlinked.
     */
    struct stat stat_buffer;
    if((lstat(file_name,&stat_buffer) == 0)){
      if((stat_buffer.st_mode & S_IFMT) == S_IFLNK){
	continue;
      }
    }
    
    /* Check if it's a directory. If so, then search it. */
    DIR *sub_dir;
    if((sub_dir = opendir(file_name)) != NULL){
      closedir(sub_dir);
      find_devs(file_name);
    }
    
    /* If not, check for optical drives, and add them to the list */
    else{
      int fd = open(file_name,(O_RDONLY | O_EXCL | O_NONBLOCK),0);
      
      if(fd >= 0){
      /* Only optical drives return > 0 on the CDROM_GET_CAPABILITY ioctl
       *
       * nvidia devices return 0 for some reason. Fortunately, there seem
       * to be no ill effects.
       */
      int caps = ioctl(fd,CDROM_GET_CAPABILITY,NULL);
      if(caps > 0){
	if(num_drives == 0){
	  optical_drives = malloc(1);
	  capabilities = malloc(sizeof(int));
	}
	else{
	  realloc(optical_drives,num_drives + 1);
	  realloc(capabilities,sizeof(int) * (num_drives + 1));
	}
	
	if(optical_drives == NULL || capabilities == NULL){
	  printf("Allocation Error!\nDrives: %p\nCapabilities: %p\n",optical_drives,capabilities);
	  return 1;
	}
	
	strcpy(optical_drives[num_drives],file_name);
	capabilities[num_drives] = caps;
	
	num_drives++;
      }
      close(fd);
      }
    }
    free(file_name);
  }
  closedir(base_dir);
  
  return 0;
}


int main(int argc, char **argv){
  num_drives = 0;
  
  int errors = find_devs("/dev");
  if(errors){
    return 0;
  }
  
  for(;num_drives > 0; --num_drives){
    char *device = optical_drives[num_drives - 1];
    int caps = capabilities[num_drives - 1];
    char *read, *write;
    read = "CD";
    write = "none";
    if(caps & CDC_CD_R)
      write = "CD-R";
    if(caps & CDC_CD_RW)
      write = "CD-RW";
    if(caps & CDC_DVD)
      read = "DVD";
    if(caps & CDC_DVD_R){
      if(strcmp(write,"CD-RW") == 0)
	write = "DVD-RW";
      else
	write = "DVD-R";
    }
    if(caps & CDC_DVD_RAM)
      write = "DVD-RAM";
    
    
    printf("Device: %s\nRead: %s\nWrite: %s\n",device,read,write);
  }
  return 0;
}
The source is also downloadable at http://personal.utulsa.edu/~chris-johnson/readdev.c

Compile it straight.
Code:
$ cc -oreaddev readdev.c
$ ./readdev
What I want to know is if this lists all of your optical drives and their capabilities. If you try this out, please take the time to respond.

(Note that I assume that a drive that can write CD-RW and DVD-R can write DVD-RW. This is because there is no flag for DVD-RW. I have never heard of a drive that could only write the former two, but not the latter, but if that is indeed the case, please tell me, and know that DVD-RW actually means that it can write CD-RW and DVD-R.)

Thanks,
Chris

Edit: Added a check that should allow devfs users to run this. Sorry if you tried it and had troubles.

Last edited by Chrax; 06-16-2005 at 11:05 PM.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Mandrake 10 DVDROM autodetection onebutters Linux - Hardware 8 02-27-2005 06:37 AM
Swap Partition Autodetection Baltor Linux - General 1 10-21-2004 08:43 PM
porting knoppix autodetection script jadermf Linux - General 6 04-03-2004 04:59 AM
Knoppix cd...autodetection seems to hang TallAmericano Linux - Newbie 2 09-29-2003 10:36 PM
Autodetection problem liuhongbo Linux - Networking 3 05-02-2003 04:46 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:31 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration