diff options
-rw-r--r-- | extras/cdsymlinks.c | 555 | ||||
-rw-r--r-- | extras/cdsymlinks.conf | 21 | ||||
-rw-r--r-- | extras/cdsymlinks.sh | 204 |
3 files changed, 0 insertions, 780 deletions
diff --git a/extras/cdsymlinks.c b/extras/cdsymlinks.c deleted file mode 100644 index b6bc96dc6f..0000000000 --- a/extras/cdsymlinks.c +++ /dev/null @@ -1,555 +0,0 @@ -/* cdsymlinks.c - * - * Map cdrom, cd-r, cdrw, dvd, dvdrw, dvdram to suitable devices. - * Prefers cd* for DVD-incapable and cdrom and dvd for read-only devices. - * First parameter is the kernel device name. - * Second parameter, if present, must be "-d" => output the full mapping. - * - * Usage: - * BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" - * BUS="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" - * BUS="scsi", KERNEL="scd[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" - * (this last one is "just in case") - * - * (c) 2004, 2005 Darren Salt <linux@youmustbejoking.demon.co.uk> - * - * Contributors: - * - J A Magallon <jamagallon@able.es> (bug fixes) - * - * Last modified: 2005-02-15 - */ - -#define _GNU_SOURCE - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> - -#include <strings.h> -#include <sys/types.h> -#include <dirent.h> - -#include <unistd.h> - -#include <wordexp.h> - -static const char *progname; - -/* This file provides us with our devices and capabilities information. */ -#define CDROM_INFO "/proc/sys/dev/cdrom/info" - -/* This file contains our default settings. */ -#define CONFIGURATION "/etc/udev/cdsymlinks.conf" -/* Default output types configuration, in the presence of an empty list */ -#define OUTPUT_DEFAULT "CD CDRW DVD DVDRW DVDRAM" - -static int debug = 0; - -/* List item */ -struct list_item_t { - struct list_item_t *next; - char *data; -}; - -/* List root. Note offset of list_t->head and list_item_t->next */ -struct list_t { - struct list_item_t *head, *tail; -}; - -/* Configuration variables */ -static struct list_t allowed_output = {0}; -static int numbered_links = 1; -static int link_zero = 0; - -/* Available devices */ -static struct list_t Devices = {0}; - -/* Devices' capabilities in full (same order as available devices list). - * There's no cap_CD; all are assumed able to read CDs. - */ -static struct list_t cap_DVDRAM = {0}, cap_DVDRW = {0}, cap_DVD = {0}, - cap_CDRW = {0}, cap_CDR = {0}, cap_CDWMRW = {0}, - cap_CDMRW = {0}, cap_CDRAM = {0}; - -/* Device capabilities by name */ -static struct list_t dev_DVDRAM = {0}, dev_DVDRW = {0}, dev_DVD = {0}, - dev_CDRW = {0}, dev_CDR = {0}, dev_CDWMRW = {0}, - dev_CDMRW = {0}, dev_CDRAM = {0}; -#define dev_CD Devices - -typedef struct { - struct list_t *cap, *dev; - const char label[8], symlink[8]; - const char *captext; - int captextlen; -} cap_dev_t; - -#define CAPDEV(X) &cap_##X, &dev_##X - -static const cap_dev_t cap_dev_info[] = { - { NULL, &dev_CD, "CD", "cdrom", NULL, 0 }, - { CAPDEV(CDR), "CDR", "cd-r", "Can write CD-R:", 15 }, - { CAPDEV(CDRW), "CDRW", "cdrw", "Can write CD-RW:", 16 }, - { CAPDEV(DVD), "DVD", "dvd", "Can read DVD:", 13 }, - { CAPDEV(DVDRW), "DVDRW", "dvdrw", "Can write DVD-R:", 16 }, - { CAPDEV(DVDRAM), "DVDRAM", "dvdram", "Can write DVD-RAM:", 18 }, - { CAPDEV(CDMRW), "CDMRW", "cdm", "Can read MRW:", 13 }, /* CDC-MRW R */ - { CAPDEV(CDWMRW), "CDWMRW", "cdmrw", "Can write MRW:", 14 }, /* CDC-MRW W */ - { CAPDEV(CDRAM), "CDRAM", "cdram", "Can write RAM:", 14 }, /* CDC-RAM W */ - { NULL } -}; - -#define foreach_cap_dev(loop) \ - for ((loop) = cap_dev_info; (loop)->label[0]; ++(loop)) -#define foreach_cap_dev_noCD(loop) \ - for ((loop) = cap_dev_info + 1; (loop)->label[0]; ++(loop)) - -/* - * Some library-like bits first... - */ - -static void -errexit (const char *reason) -{ - fprintf (stderr, "%s: %s: %s\n", progname, reason, strerror (errno)); - exit (2); -} - - -static void -msgexit (const char *reason) -{ - fprintf (stderr, "%s: %s\n", progname, reason); - exit (2); -} - - -static void -errwarn (const char *reason) -{ - fprintf (stderr, "%s: warning: %s: %s\n", progname, reason, strerror (errno)); -} - - -static void -msgwarn (const char *reason) -{ - fprintf (stderr, "%s: warning: %s\n", progname, reason); -} - - -static void * -xmalloc (size_t size) -{ - void *mem = malloc (size); - if (size && !mem) - msgexit ("malloc failed"); - return mem; -} - - -static char * -xstrdup (const char *text) -{ - char *mem = xmalloc (strlen (text) + 1); - return strcpy (mem, text); -} - - -/* Append a string to a list. The string is duplicated. */ -static void -list_append (struct list_t *list, const char *data) -{ - struct list_item_t *node = xmalloc (sizeof (struct list_item_t)); - node->next = NULL; - if (list->tail) - list->tail->next = node; - list->tail = node; - if (!list->head) - list->head = node; - node->data = xstrdup (data); -} - - -/* Prepend a string to a list. The string is duplicated. */ -static void -list_prepend (struct list_t *list, const char *data) -{ - struct list_item_t *node = xmalloc (sizeof (struct list_item_t)); - node->next = list->head; - list->head = node; - if (!list->tail) - list->tail = node; - node->data = xstrdup (data); -} - - -/* Delete a lists's contents, freeing claimed memory */ -static void -list_delete (struct list_t *list) -{ - struct list_item_t *node = list->head; - while (node) - { - struct list_item_t *n = node; - node = node->next; - free (n->data); - free (n); - } - list->tail = list->head = NULL; -} - - -/* Print out a list on one line, each item space-prefixed, no LF */ -static void -list_print (const struct list_t *list, FILE *stream) -{ - const struct list_item_t *node = (const struct list_item_t *)list; - while ((node = node->next) != NULL) - fprintf (stream, " %s", node->data); -} - - -/* Return the nth item in a list (count from 0) - * If there aren't enough items in the list, return the requested default - */ -static const struct list_item_t * -list_nth (const struct list_t *list, size_t nth) -{ - const struct list_item_t *node = list->head; - while (nth && node) - { - node = node->next; - --nth; - } - return node; -} - - -/* Return the first matching item in a list, or NULL */ -static const struct list_item_t * -list_search (const struct list_t *list, const char *data) -{ - const struct list_item_t *node = list->head; - while (node) - { - if (!strcmp (node->data, data)) - return node; - node = node->next; - } - return NULL; -} - - -/* Split up a string on whitespace & assign the resulting tokens to a list. - * Ignore everything up until the first colon (if present). - */ -static void -list_assign_split (struct list_t *list, char *text) -{ - char *token = strchr (text, ':'); - token = strtok (token ? token + 1 : text, " \t\n"); - while (token) - { - list_prepend (list, token); - token = strtok (0, " \t\n"); - } -} - - - -/* Gather the default settings. */ -static void -read_defaults (void) -{ - FILE *conf = fopen (CONFIGURATION, "r"); - if (!conf) - { - if (errno != ENOENT) - errwarn ("error accessing configuration"); - } - else - { - char *text = NULL; - size_t textlen; - while (getline (&text, &textlen, conf) != -1) - { - wordexp_t p = {0}; - int len = strlen (text); - if (len && text[len - 1] == '\n') - text[--len] = '\0'; - if (len && text[len - 1] == '\r') - text[--len] = '\0'; - if (!len) - continue; - char *token = text + strspn (text, " \t"); - if (!*token || *token == '#') - continue; - switch (len = wordexp (text, &p, 0)) - { - case WRDE_NOSPACE: - msgexit ("malloc failed"); - case 0: - if (p.we_wordc == 1) - { - if (!strncmp (p.we_wordv[0], "OUTPUT=", 7)) - { - list_delete (&allowed_output); - list_assign_split (&allowed_output, p.we_wordv[0] + 7); - } - else if (!strncmp (p.we_wordv[0], "NUMBERED_LINKS=", 15)) - numbered_links = atoi (p.we_wordv[0] + 15); - else if (!strncmp (p.we_wordv[0], "LINK_ZERO=", 15)) - link_zero = atoi (p.we_wordv[0] + 15); - break; - } - /* fall through */ - default: - msgwarn ("syntax error in configuration file"); - } - wordfree (&p); - } - if (!feof (conf)) - errwarn ("error accessing configuration"); - if (fclose (conf)) - errwarn ("error accessing configuration"); - free (text); - } - if (!allowed_output.head) - { - char *dflt = strdup (OUTPUT_DEFAULT); - list_assign_split (&allowed_output, dflt); - free (dflt); - } -} - - -/* From information supplied by the kernel: - * + get the names of the available devices - * + populate our capability lists - * Order is significant: device item N maps to each capability item N. - */ -static void -populate_capability_lists (void) -{ - FILE *info = fopen (CDROM_INFO, "r"); - if (!info) - { - if (errno == ENOENT) - exit (0); - errexit ("error accessing CD/DVD info"); - } - - char *text = 0; - size_t textlen = 0; - - while (getline (&text, &textlen, info) != -1) - { - if (!strncasecmp (text, "drive name", 10)) - list_assign_split (&Devices, text); - else - { - const cap_dev_t *cap; - foreach_cap_dev_noCD (cap) - if (!strncasecmp (text, cap->captext, cap->captextlen)) - { - list_assign_split (cap->cap, text); - break; - } - } - } - if (!feof (info)) - errexit ("error accessing CD/DVD info"); - fclose (info); - free (text); -} - - -/* Write out the links of type LINK which should be created for device NAME, - * taking into account existing links and the capability list for type LINK. - */ -static void -do_output (const char *name, const char *link, const struct list_t *dev, - int do_link_zero) -{ - const struct list_item_t *i = (const struct list_item_t *)dev; - if (!i->next) - return; - - errno = 0; - - size_t link_len = strlen (link); - DIR *dir = opendir ("/dev"); - if (!dir) - errexit ("error reading /dev"); - - struct list_t devls = {0}; /* symlinks whose name matches LINK */ - struct list_t devlinks = {0}; /* those symlinks' targets */ - struct dirent *entry; - while ((entry = readdir (dir)) != NULL) - { - if (strncmp (entry->d_name, link, link_len)) - continue; /* wrong name: ignore it */ - - /* The rest of the name must be null or consist entirely of digits. */ - const char *p = entry->d_name + link_len - 1; - while (*++p) - if (!isdigit (*p)) - break; - if (*p) - continue; /* wrong format - ignore */ - - /* Assume that it's a symlink and try to read its target. */ - char buf[sizeof (entry->d_name)]; - int r = readlink (entry->d_name, buf, sizeof (buf) - 1); - if (r < 0) - { - if (errno == EINVAL) - continue; /* not a symlink - ignore */ - errexit ("error reading link in /dev"); - } - /* We have the name and the target, so update our lists. */ - buf[r] = 0; - list_append (&devls, entry->d_name); - list_append (&devlinks, buf); - } - if (errno) - errexit ("error reading /dev"); - if (closedir (dir)) - errexit ("error closing /dev"); - - /* Now we write our output... */ - size_t count = 0; - while ((i = i->next) != NULL) - { - int isdev = !strcmp (name, i->data); /* current dev == target dev? */ - int present = 0; - size_t li = -1; - const struct list_item_t *l = (const struct list_item_t *)&devlinks; - - /* First, we look for existing symlinks to the target device. */ - while (++li, (l = l->next) != NULL) - { - if (strcmp (l->data, i->data)) - continue; - /* Existing symlink found - don't output a new one. - * If ISDEV, we output the name of the existing symlink. - */ - if (do_link_zero) - return; - present = 1; - if (isdev) - printf (" %s", list_nth (&devls, li)->data); - } - - /* If we found no existing symlinks for the target device... */ - if (!present) - { - char buf[256]; - snprintf (buf, sizeof (buf), count || do_link_zero ? "%s%d" : "%s", - link, count); - /* Find the next available (not present) symlink name. - * We always need to do this for reasons of output consistency: if a - * symlink is created by udev as a result of use of this program, we - * DON'T want different output! - */ - while (list_search (&devls, buf)) - { - if (do_link_zero) - return; - snprintf (buf, sizeof (buf), "%s%d", link, ++count); - } - /* If ISDEV, output it. */ - if (isdev && (numbered_links || count == 0)) - printf (" %s", buf); - /* If the link isn't in our "existing links" list, add it and increment - * our counter. - */ - if (!list_search (&devls, buf)) - { - if (do_link_zero) - return; - list_append (&devls, buf); - ++count; - } - } - } - - list_delete (&devls); - list_delete (&devlinks); -} - - -/* Populate a device list from a capabilities list. */ -static void -populate_device_list (struct list_t *out, const struct list_t *caps) -{ - const struct list_item_t *cap, *dev; - cap = (const struct list_item_t *)caps; - dev = (const struct list_item_t *)&Devices; - while ((cap = cap->next) != NULL && (dev = dev->next) != NULL) - if (cap->data[0] != '0') - list_append (out, dev->data); -} - - -int -main (int argc, char *argv[]) -{ - const cap_dev_t *capdev; - - progname = argv[0]; - debug = argc > 2 && !strcmp (argv[2], "-d"); - - if (argc < 2 || argc > 2 + debug) - msgexit ("usage: cdsymlinks DEVICE [-d]"); - - if (chdir ("/dev")) - errexit ("can't chdir /dev"); - - read_defaults (); - populate_capability_lists (); - - /* Construct the device lists from the capability lists. - * (We assume that all relevant devices can read CDs.) - */ - foreach_cap_dev_noCD (capdev) - populate_device_list (capdev->dev, capdev->cap); - - if (debug) - { - printf ("Devices:"); - const struct list_item_t *item = (const struct list_item_t *)&Devices; - while ((item = item->next) != NULL) - printf (" %s", item->data); - - printf ("\nCDROM : (all)"); - item = (const struct list_item_t *)&dev_CD; - while ((item = item->next) != NULL) - printf (" %s", item->data); - puts (""); - - foreach_cap_dev_noCD (capdev) - { - printf ("%-10s:", capdev->label); - list_print (capdev->cap, stdout); - list_print (capdev->dev, stdout); - puts (""); - } - - } - - /* Write the symlink names. */ - foreach_cap_dev (capdev) - if (list_search (&allowed_output, capdev->label)) - { - do_output (argv[1], capdev->symlink, capdev->dev, 0); - if (link_zero) - do_output (argv[1], capdev->symlink, capdev->dev, 1); - } - puts (""); - - return 0; -} diff --git a/extras/cdsymlinks.conf b/extras/cdsymlinks.conf deleted file mode 100644 index e4c5ee2231..0000000000 --- a/extras/cdsymlinks.conf +++ /dev/null @@ -1,21 +0,0 @@ -# Configuration file for cdsymlinks - -# Output links for these types of devices. -# Allowed keywords are: corresponding to device names: -# CD CDR CDRW cdrom cd-r cdrw -# DVD DVDRW DVDRAM dvd dvdrw dvdram -# CDMRW CDWMRW cdm cdmrw -# CDRAM cdram -# Other words are accepted but ignored. -# Devices with multiple recognised capabilities WILL get multiple links. -#OUTPUT="CD CDRW DVD DVDRW DVDRAM" - -# Whether to output numbered links. -# 1 = output 'cdrom1', 'dvd1' etc. for other devices -# 0 = don't output 'cdrom1', 'dvd1' etc. -# We always output 'cdrom', 'dvd' etc. for the best-match devices. -#NUMBERED_LINKS=1 - -# Whether to output link 0 along with each unnumbered link. -# (No effect if NUMBERED_LINKS=0.) -#LINK_ZERO=0 diff --git a/extras/cdsymlinks.sh b/extras/cdsymlinks.sh deleted file mode 100644 index 592de365cb..0000000000 --- a/extras/cdsymlinks.sh +++ /dev/null @@ -1,204 +0,0 @@ -#! /bin/sh -e -# -# Map cdrom, cd-r, cdrw, dvd, dvdrw, dvdram, cdm, cdmrw, cdram -# to suitable devices. -# Prefers cd* for DVD-incapable and cdrom and dvd for read-only devices. -# First parameter is the kernel device name. -# Second parameter, if present, must be "-d" => output the full mapping. -# -# Usage: -# BUS="ide", KERNEL="hd[a-z]", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -# BUS="scsi", KERNEL="sr[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -# BUS="scsi", KERNEL="scd[0-9]*", PROGRAM="/etc/udev/cdsymlinks.sh %k", SYMLINK="%c{1} %c{2} %c{3} %c{4} %c{5} %c{6}" -# (this last one is "just in case") -# -# (c) 2004, 2005 Darren Salt <linux@youmustbejoking.demon.co.uk> -# -# Last modified: 2005-02-15 - -test -e /proc/sys/dev/cdrom/info || exit 0 - -# Defaults; it's better that you alter them in /etc/udev/cdsymlinks.conf -OUTPUT='CD CDRW DVD DVDRW DVDRAM' -NUMBERED_LINKS=1 -LINK_ZERO=0 - -test -e /etc/udev/cdsymlinks.conf && . /etc/udev/cdsymlinks.conf - -DEBUG='' -test "$2" = '-d' && DEBUG=1 - - -# Array emulation. 'setArray FOO a b c' gives FOO=3 FOO_1=a FOO_2=b FOO_3=c -setArray () { - local _ARRAY=$1 - local _INDEX=0 - shift - while test $# -ne 0; do - eval ${_ARRAY}_$_INDEX="$1" - _INDEX=$(($_INDEX+1)) - shift - done - eval $_ARRAY=$_INDEX -} - -ix () { eval echo -n \$$1_$2; } -ixs () { eval $1_$2="$3"; } - -# Args: variable, value -# Returns true if value is not in variable (a whitespace-separated list) -notin () { - test "$2" = '' && return 0 - local i - for i in `eval echo '$'$1`; do - test "$i" != "$2" || return 1 - done -} - - -# Scan /proc/sys/dev/cdrom/info for details on the present devices -setArray DEVICES `sed -re '/^drive name:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray DVDRAMs `sed -re '/^Can write DVD-RAM:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray DVDRWs `sed -re '/^Can write DVD-R:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray DVDs `sed -re '/^Can read DVD:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray CDRWs `sed -re '/^Can write CD-RW:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray CDRs `sed -re '/^Can write CD-R:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray CDMRWs `sed -re '/^Can write MRW:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray CDMs `sed -re '/^Can read MRW:/I! d; s/.*://' /proc/sys/dev/cdrom/info` -setArray CDRAMs `sed -re '/^Can write RAM:/I! d; s/.*://' /proc/sys/dev/cdrom/info` - -# How many devices do we have? -NumDevs=$(($DEVICES-1)) -Count='' -i=-1 -while test $i -ne $NumDevs; do - i=$(($i+1)); - Count="$i${Count:+ }$Count"; -done - -# Fill in any missing capabilities information (assume not capable) -for i in $Count; do - test "`ix DVDRAMs $i`" != '' || ixs DVDRAMs $i 0 - test "`ix DVDRWs $i`" != '' || ixs DVDRWs $i 0 - test "`ix DVDs $i`" != '' || ixs DVDs $i 0 - test "`ix CDRWs $i`" != '' || ixs CDRWs $i 0 - test "`ix CDRs $i`" != '' || ixs CDRs $i 0 - test "`ix CDMRWs $i`" != '' || ixs CDMRWs $i 0 - test "`ix CDMs $i`" != '' || ixs CDMs $i 0 - test "`ix CDRAMs $i`" != '' || ixs CDRAMs $i 0 -done - -DVDRAM='' -DVDRW='' -DVD='' -CDRW='' -CDR='' -CDMRW='' -CDM='' -CDRAM='' -CD='' - -# Calculate symlink->device mappings. -# We need to be careful about how we assign mappings because we want -# read-only devices to have /dev/cdrom and /dev/dvd. -# Hot-plugged CD/DVD devices may well cause this scheme some problems. -for i in $Count; do - test "`ix DVDRAMs $i`" = 1 && DVDRAM="$DVDRAM `ix DEVICES $i`" -done -for i in $Count; do - test "`ix DVDRWs $i`" = 1 && DVDRW="$DVDRW `ix DEVICES $i`" -done -for i in $Count; do - test "`ix DVDs $i`" = 1 && DVD="$DVD `ix DEVICES $i`" -done -for i in $Count; do - test "`ix CDRWs $i`" = 1 && CDRW="$CDRW `ix DEVICES $i`" -done -for i in $Count; do - test "`ix CDRs $i`" = 1 && CDR="$CDR `ix DEVICES $i`" -done -for i in $Count; do - test "`ix CDMRWs $i`" = 1 && CDMRW="$CDMRW `ix DEVICES $i`" -done -for i in $Count; do - test "`ix CDMs $i`" = 1 && CDM="$CDM `ix DEVICES $i`" -done -for i in $Count; do - test "`ix CDRAMs $i`" = 1 && CDRAM="$CDRAM `ix DEVICES $i`" -done -for i in $Count; do - CD="$CD `ix DEVICES $i`" -done - -# Debug output -if test "$DEBUG" = 1; then - echo 'Devices:' `for i in $Count; do ix DEVICES $i; echo -n \ ; done` - echo 'CDROM : (all)' $CD - echo 'CD-R :' `for i in $Count; do ix CDRs $i; echo -n \ ; done` $CDR - echo 'CDRW :' `for i in $Count; do ix CDRWs $i; echo -n \ ; done` $CDRW - echo 'DVD :' `for i in $Count; do ix DVDs $i; echo -n \ ; done` $DVD - echo 'DVDRW :' `for i in $Count; do ix DVDRWs $i; echo -n \ ; done` $DVDRW - echo 'DVDRAM :' `for i in $Count; do ix DVDRAMs $i; echo -n \ ; done` $DVDRAM - echo 'CDMRW :' `for i in $Count; do ix CDMRWs $i; echo -n \ ; done` $CDMRW - echo 'CDWMRW :' `for i in $Count; do ix CDMs $i; echo -n \ ; done` $CDM - echo 'CDRAM :' `for i in $Count; do ix CDRAMs $i; echo -n \ ; done` $CDRAM -fi - -# Prepare symlink names output -do_output () { - test "`eval echo '$'$3`" = '' && return - local i - local COUNT=$4 - local DEVLS="`ls -dl \"/dev/$2\" \"/dev/$2\"[0-9]* 2>/dev/null`" - local PRESENT="`echo "$DEVLS" | - sed -re 's!^.* /dev/('$2'[[:digit:]]*) -> [^[:space:]]+$!\1!'`" - for i in `eval echo '$'$3`; do - # First, we look for existing symlinks to the target device. - local DEVPRESENT="`echo "$DEVLS" | - sed -re 's!^.* /dev/('$2'[[:digit:]]*) -> '$i'$!\1!; t X; d; :X'`" - if test "$DEVPRESENT" != ""; then - # Existing symlinks found - don't output a new one. - # If the target dev ($1) is the current dev ($i), we output their names. - test -z "$4" || return; - test "$1" = "$i" && echo " $DEVPRESENT" | sed -e 'N; $ s/\n/ /' - else - # If we found no existing symlinks for the target device... - # Find the next available (not present) symlink name. - # We always need to do this for reasons of output consistency: if a - # symlink is created by udev as a result of use of this program, we - # DON'T want different output! - until notin PRESENT "$2$COUNT"; do - test -z "$4" || return; - COUNT=$(($COUNT+1)) - done - # If the target dev ($1) is the current dev ($i), we output its name. - if test $(($NUMBERED_LINKS)) -ne 0 || test -z "$COUNT"; then - test "$i" != "$1" || echo -n " $2$COUNT" - fi - # If the link isn't in our "existing links" list, add it and increment - # our counter. - if notin PRESENT "$2$COUNT"; then - test -z "$4" || return; - PRESENT="$PRESENT\n$2$COUNT" - COUNT=$(($COUNT+1)) - fi - fi - done -} - -output () { - do_output "$@" - test $(($LINK_ZERO)) -eq 0 || do_output "$@" 0 -} - -# And output it -notin OUTPUT CD || echo -n "`output "$1" cdrom CD`" -notin OUTPUT CDR || echo -n "`output "$1" cd-r CDR`" -notin OUTPUT CDRW || echo -n "`output "$1" cdrw CDRW`" -notin OUTPUT DVD || echo -n "`output "$1" dvd DVD`" -notin OUTPUT DVDRW || echo -n "`output "$1" dvdrw DVDRW`" -notin OUTPUT DVDRAM || echo -n "`output "$1" dvdram DVDRAM`" -notin OUTPUT CDMRW || echo -n "`output "$1" cdmrw CDM`" -notin OUTPUT CDWMRW || echo -n "`output "$1" cdwmrw CDMRW`" -notin OUTPUT CDRAM || echo -n "`output "$1" cdram CDRAM`" -echo |