Search
lxdream.org :: lxdream/src/drivers/cdrom/drive.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/cdrom/drive.c
changeset 1099:566cdeb157ec
prev1097:d4807997e450
next1296:30ecee61f811
author nkeynes
date Wed Feb 10 18:16:19 2010 +1000 (10 years ago)
permissions -rw-r--r--
last change First draft of basic ISO9660 filesystem reader
file annotate diff log raw
nkeynes@1097
     1
/**
nkeynes@1097
     2
 * $Id$
nkeynes@1097
     3
 *
nkeynes@1097
     4
 * Host CD/DVD drive support.
nkeynes@1097
     5
 *
nkeynes@1097
     6
 * Copyright (c) 2009 Nathan Keynes.
nkeynes@1097
     7
 *
nkeynes@1097
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@1097
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@1097
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@1097
    11
 * (at your option) any later version.
nkeynes@1097
    12
 *
nkeynes@1097
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@1097
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@1097
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@1097
    16
 * GNU General Public License for more details.
nkeynes@1097
    17
 */
nkeynes@1097
    18
nkeynes@1097
    19
#include <stdlib.h>
nkeynes@1099
    20
#include <string.h>
nkeynes@1097
    21
#include <glib/gstrfuncs.h>
nkeynes@1097
    22
#include <glib/gmem.h>
nkeynes@1097
    23
#include "drivers/cdrom/drive.h"
nkeynes@1097
    24
#include "drivers/cdrom/cdimpl.h"
nkeynes@1097
    25
nkeynes@1097
    26
static GList *cdrom_drive_list;
nkeynes@1097
    27
nkeynes@1097
    28
static cdrom_drive_t cdrom_drive_new( const char *name, const char *display_name, cdrom_drive_open_fn_t open_fn )
nkeynes@1097
    29
{
nkeynes@1097
    30
    cdrom_drive_t drive = g_malloc0( sizeof(struct cdrom_drive) );
nkeynes@1097
    31
    drive->name = g_strdup(name);
nkeynes@1097
    32
    drive->display_name = g_strdup(display_name);
nkeynes@1097
    33
    drive->open = open_fn;
nkeynes@1097
    34
    return drive;
nkeynes@1097
    35
}
nkeynes@1097
    36
nkeynes@1097
    37
static void cdrom_drive_destroy( cdrom_drive_t drive )
nkeynes@1097
    38
{
nkeynes@1097
    39
    g_free( (char *)drive->name );
nkeynes@1097
    40
    drive->name = NULL;
nkeynes@1097
    41
    g_free( (char *)drive->display_name );
nkeynes@1097
    42
    drive->display_name = NULL;
nkeynes@1097
    43
    g_free( drive );
nkeynes@1097
    44
}
nkeynes@1097
    45
nkeynes@1097
    46
GList *cdrom_drive_get_list()
nkeynes@1097
    47
{
nkeynes@1097
    48
    return cdrom_drive_list;
nkeynes@1097
    49
}
nkeynes@1097
    50
nkeynes@1097
    51
cdrom_drive_t cdrom_drive_add( const char *name, const char *display_name, cdrom_drive_open_fn_t open_fn )
nkeynes@1097
    52
{
nkeynes@1097
    53
    for( GList *ptr = cdrom_drive_list; ptr != NULL; ptr = ptr->next ) {
nkeynes@1097
    54
        cdrom_drive_t it = (cdrom_drive_t)ptr->data;
nkeynes@1097
    55
        if( strcmp(it->name, name) == 0 ) {
nkeynes@1097
    56
            return it;
nkeynes@1097
    57
        }
nkeynes@1097
    58
    }
nkeynes@1097
    59
nkeynes@1097
    60
    cdrom_drive_t new_drive = cdrom_drive_new(name,display_name,open_fn);
nkeynes@1097
    61
    cdrom_drive_list = g_list_append( cdrom_drive_list, new_drive );
nkeynes@1097
    62
    return new_drive;
nkeynes@1097
    63
}
nkeynes@1097
    64
nkeynes@1097
    65
gboolean cdrom_drive_remove( const char *name )
nkeynes@1097
    66
{
nkeynes@1097
    67
    for( GList *ptr = cdrom_drive_list; ptr != NULL; ptr = ptr->next ) {
nkeynes@1097
    68
        cdrom_drive_t it = (cdrom_drive_t)ptr->data;
nkeynes@1097
    69
        if( strcmp(it->name, name) == 0 ) {
nkeynes@1097
    70
            cdrom_drive_list = g_list_delete_link( cdrom_drive_list, ptr );
nkeynes@1097
    71
            cdrom_drive_destroy(it);
nkeynes@1097
    72
            return TRUE;
nkeynes@1097
    73
        }
nkeynes@1097
    74
    }
nkeynes@1097
    75
    return FALSE;
nkeynes@1097
    76
}
nkeynes@1097
    77
nkeynes@1097
    78
void cdrom_drive_remove_all()
nkeynes@1097
    79
{
nkeynes@1097
    80
    for( GList *ptr = cdrom_drive_list; ptr != NULL; ptr = ptr->next ) {
nkeynes@1097
    81
        cdrom_drive_destroy( (cdrom_drive_t)ptr->data );
nkeynes@1097
    82
    }
nkeynes@1097
    83
    g_list_free(cdrom_drive_list);
nkeynes@1097
    84
    cdrom_drive_list = NULL;
nkeynes@1097
    85
}
nkeynes@1097
    86
nkeynes@1097
    87
cdrom_drive_t cdrom_drive_get_index( unsigned int index )
nkeynes@1097
    88
{
nkeynes@1097
    89
    return (cdrom_drive_t)g_list_nth_data(cdrom_drive_list, index);
nkeynes@1097
    90
}
nkeynes@1097
    91
nkeynes@1097
    92
cdrom_disc_t cdrom_drive_open( cdrom_drive_t drive, ERROR *err )
nkeynes@1097
    93
{
nkeynes@1097
    94
    return drive->open(drive, err);
nkeynes@1097
    95
}
nkeynes@1097
    96
nkeynes@1097
    97
cdrom_drive_t cdrom_drive_find( const char *name )
nkeynes@1097
    98
{
nkeynes@1097
    99
    const char *id = name;
nkeynes@1097
   100
nkeynes@1097
   101
    /* If we have no drives, just return NULL without looking, to save time */
nkeynes@1097
   102
    if( cdrom_drive_list == NULL )
nkeynes@1097
   103
        return NULL;
nkeynes@1097
   104
nkeynes@1097
   105
    /* Check for a url-style name */
nkeynes@1097
   106
    const char *lizard_lips = strstr( name, "://" );
nkeynes@1097
   107
    if( lizard_lips != NULL ) {
nkeynes@1097
   108
        id = lizard_lips + 3;
nkeynes@1097
   109
        int method_len = (lizard_lips-name);
nkeynes@1097
   110
        if( method_len > 8 )
nkeynes@1097
   111
            return NULL;
nkeynes@1097
   112
nkeynes@1097
   113
        char method[method_len + 1];
nkeynes@1097
   114
        memcpy( method, name, method_len );
nkeynes@1097
   115
        method[method_len] = '\0';
nkeynes@1097
   116
nkeynes@1097
   117
        if( strcasecmp( method, "file" ) != 0 &&
nkeynes@1097
   118
            strcasecmp( method, "dvd" ) != 0 &&
nkeynes@1097
   119
            strcasecmp( method, "cd" ) != 0 &&
nkeynes@1097
   120
            strcasecmp( method, "cdrom" ) ) {
nkeynes@1097
   121
            /* Anything else we don't try to recognize */
nkeynes@1097
   122
            return NULL;
nkeynes@1097
   123
        }
nkeynes@1097
   124
nkeynes@1097
   125
        if( *id == '\0' ) {
nkeynes@1097
   126
            /* Accept eg  'dvd://' as meaning 'the first cd/dvd device */
nkeynes@1097
   127
            return cdrom_drive_list->data;
nkeynes@1097
   128
        }
nkeynes@1097
   129
nkeynes@1097
   130
        char *endp = NULL;
nkeynes@1097
   131
        unsigned long index = strtoul( id, &endp, 10 );
nkeynes@1097
   132
        if( endp != NULL && *endp == '\0' ) {
nkeynes@1097
   133
            /* Accept eg 'dvd://2' as meaning 'the second cd/dvd device */
nkeynes@1097
   134
            return cdrom_drive_get_index(index);
nkeynes@1097
   135
        }
nkeynes@1097
   136
nkeynes@1097
   137
        /* Otherwise it must be a drive identifier, so treat it as if it didn't
nkeynes@1097
   138
         * have the url prefix. (fallthrough)
nkeynes@1097
   139
         */
nkeynes@1097
   140
    }
nkeynes@1097
   141
nkeynes@1097
   142
    for( GList *ptr = cdrom_drive_list; ptr != NULL; ptr = ptr->next ) {
nkeynes@1097
   143
        cdrom_drive_t drive = (cdrom_drive_t)ptr->data;
nkeynes@1097
   144
        if( strcmp(drive->name, id) == 0 )
nkeynes@1097
   145
            return drive;
nkeynes@1097
   146
    }
nkeynes@1097
   147
nkeynes@1097
   148
    return NULL;
nkeynes@1097
   149
}
.