4c4 < * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007,2008 Free Software Foundation, Inc. --- > * Copyright (C) 1999,2000,2001,2002,2003,2004,2006,2007 Free Software Foundation, Inc. 37a38 > #include 78a80,85 > #ifdef __FreeBSD__ > # include > # include > # include > #endif > 105c112 < if ((name[0] != 'f' && name[0] != 'h') || name[1] != 'd') --- > if ((name[0] != 'f' && name[0] != 'h') || name[1] != 'd') // allow only 'fd' or 'hd' 196a204,254 > #elif defined (__FreeBSD__) > /* To get the amound of sector from FreeBSD, we must uses ioctl(2). > ** > ** DIOCGSECTORSIZE is for the sector size of the unit (unsigned int). > ** DIOCGMEDIASIZE is for the total amound of bytes on the media(off_t or unsigned long long. > ** total_sectors = media_size devided by sector_size > */ > { > unsigned long long media; > unsigned int sector; > int fd; > char *msg; > > grub_errno = GRUB_ERR_NONE; > > fd = open (map[drive], O_RDONLY); > if ( fd == -1 ) > (void) grub_fatal ("Failed to open `%s' associated to `%s'. %s\n", map[drive], name, strerror(errno)); > > if ( ioctl (fd, DIOCGSECTORSIZE, §or) ) > { > grub_errno = GRUB_ERR_IOCTL; > msg = "Failed to get the media's sector size."; > } > else if ( ioctl (fd, DIOCGMEDIASIZE, &media) ) > { > grub_errno = GRUB_ERR_IOCTL; > msg = "Failed to get the media's size."; > } > else if ( media % sector != 0 ) > { > grub_errno = GRUB_ERR_BAD_DEVICE; > msg = "Unaligned device size."; > } > else > disk->total_sectors = media / sector; > > close (fd); > > if ( grub_errno != GRUB_ERR_NONE ) > { > char *str = NULL; > if ( grub_errno == GRUB_ERR_IOCTL ) > str = strerror (errno); > grub_error (grub_errno, "Unable to open %s correctly. %s %s", map[drive], msg, str?str:""); > } > > grub_util_info ("the size of %s is %llu sectors", name, disk->total_sectors); > return grub_errno; > } > 428c486 < /* Work around a bug in Linux ez remapping. Linux remaps all --- > /* Work around a bug in linux's ez remapping. Linux remaps all 612c670 < if (strncmp ("ide/", p, 4) == 0) --- > if (strncmp ("/dev/ide/", p, 9) == 0) 622c680 < if (strncmp ("scsi/", p, 5) == 0) --- > if (strncmp ("/dev/scsi/", p, 10) == 0) 683c741 < if (map[i] && strcmp (map[i], os_disk) == 0) --- > if (map[i] && strncmp (map[i], os_disk, strlen (map[i])) == 0) 712c770 < --- > #ifndef __FreeBSD__ 715c773 < --- > #endif 852a911,955 > #elif defined(__FreeBSD__) > /* FreeBSD uses: /.+/([a-zA-Z0-9]+)([0-9]+)s([1234])([a-zA-Z]) > where: > $1 = driver name (ad sd fd ...) > $2 = driver unit > $3 = slice unit (1-4) > $4 = label unit (a-z) > > We must extract $3 and $4. > */ > { > int ret, dos_part = -1, bsd_part = -1; > regex_t re; > char *re_str = "/.+/([-a-zA-Z0-9_]+)([0-9]+)s([1-4])([a-zA-Z])"; > #define RE_EBUF_SIZE 4096 > char ebuf[RE_EBUF_SIZE]; > #ifdef N_MATCHES > # define SAVED_N_MATCHES N_MATCHES > # undef N_MATCHES > #endif > #define N_MATCHES 5 > regmatch_t matches[N_MATCHES]; > ret = regcomp (&re, re_str, REG_EXTENDED); > if ( ret ) > { > regerror (ret, &re, ebuf, RE_EBUF_SIZE); > grub_util_error ("Std1003.2 Regular Expression compilation on `%s': %s", > re_str, ebuf); > } > ret = regexec (&re, os_dev, N_MATCHES, matches, 0); > if ( ret ) > { > regerror (ret, &re, ebuf, RE_EBUF_SIZE); > grub_util_error ("Std1003.2 Regular Expression execution on `%s': %s", > os_dev, ebuf); > } > regfree (&re); > dos_part = strtol (os_dev+matches[3].rm_so, NULL, 10) -1; > bsd_part = *(os_dev+matches[4].rm_so) - 'a'; > return make_device_name (drive, dos_part, bsd_part); > } > #undef N_MATCHES > # ifdef SAVED_N_MATCHES > # define N_MATCHES SAVED_N_MATCHES > #endif