label_dos.c revision 18c2aff776a775d34a4c9893a4c72e0434d68e36
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include "vold.h"
extern char *laread_res_to_str(enum laread_res);
extern ulong_t unique_key(char *, char *);
/*
*/
#define DOS_NAMELEN_REG PCFNAMESIZE
#define DOS_NAMELEN_EXT PCFEXTSIZE
#define DOS_VERSION 2
/*
* Number of bytes in the "volume header" located in sector
* 0 on a DOS disk.
*/
#define DOS_LABLEN 0x3e
/*
* Offset in the volume header of the pseudo-random id number.
* This is only valid for DOS version 4.0 and later.
*/
#define DOS_ID_OFF 0x27
/*
* Offset in the volume header of the ascii name of the volume.
* This is only valid for dos 4.0 and later.
*/
#define DOS_NAME_OFF 0x2b
/*
* location and length of the OEM name and version
*/
#define DOS_OEM_NAME 0x3
#define DOS_OEM_LENGTH 8
/*
* OEM name of NEC 2.0 floppies
*/
#define DOS_OEM_NEC2 "NEC 2.00"
#define NUMBUFLEN 512
/*
* Values for dos_type
*/
#define DOS_UNKNOWN 0
#define DOS_CDROM 1
#define DOS_MO 2
#define DOS_FLOPPY 3
#define DOS_DISK 4
#define DOS_PCMEM 5
struct dos_label {
};
#define DOS_LABEL_SIZE sizeof (struct dos_label)
dos_key, /* l_key */
dos_compare, /* l_compare */
dos_read, /* l_read */
NULL, /* l_write */
dos_setup, /* l_setup */
dos_xdr, /* l_xdr */
DOS_LABEL_SIZE, /* l_size */
DOS_LABEL_SIZE, /* l_xdrsize */
PCFS_LTYPE, /* l_ident */
1, /* l_nll */
&dos_labelloc, /* l_ll */
};
/*
* Forward declarations of private functions
*/
static void dirname_to_volname(char *volname,
static bool_t dos_filename_char(char c);
static int dos_label_char(int c);
/*
* Definitions of the functions that implement the label interface.
*/
label_init(void)
{
return (TRUE);
}
static char *
{
}
static bool_t
{
} else {
}
return (match);
}
static enum laread_res
{
int partition_number;
enum laread_res result;
offset = 0L;
}
}
}
/*
* For the time being, until we can overcome
* the volume code's inability to handle multiple
* DOS partitions, we set the partition mask for
* the volume to indicate that only the default
* partition is mountable.
*/
#ifdef i386
#else
#endif
} else {
}
}
return (result);
}
static void
{
case DOS_FLOPPY:
v->v_mtype = FLOPPY_MTYPE;
break;
case DOS_CDROM:
v->v_mtype = CDROM_MTYPE;
break;
case DOS_MO:
break;
case DOS_DISK:
v->v_mtype = RMDISK_MTYPE;
break;
case DOS_PCMEM:
v->v_mtype = PCMEM_MTYPE;
break;
case DOS_UNKNOWN:
default:
v->v_mtype = OTHER_MTYPE;
}
}
v->v_mtype);
}
} else {
v->v_mtype);
}
}
static void
{
char *volnamep;
/*
* xdr_string encodes a string as an integer equal
* to the length of the string, followed by the
* string itself
*/
}
if (op == XDR_ENCODE) {
xdr_destroy(&xdrs);
} else if (op == XDR_DECODE) {
l->l_label =
}
/*
* Version check. As yet there's no algorithm for
* handling different versions of the DOS label
* structure.
*/
/*
* xdr_string seems not to allocate any memory for
* null strings; therefore volnamep is null on return.
*/
}
xdr_destroy(&xdrs);
}
}
/*
* Definitions of private functions
*/
static void
{
int dirname_index;
int test_char;
int volname_index;
dirname_index = 0;
volname_index = 0;
}
dirname_index = 0;
}
}
/*
* copied from pc_validchar() in the kernel
*
* isdigit(), isupper(), ..., aren't used because they're
* character-set-dependent, but DOS isn't
*/
static bool_t
dos_filename_char(char c)
{
static char valid_chars[] = {
"$#&@!%()-{}<>`_\\^~|'"
};
char *charp;
/*
* Should be "$#&@!%()-{}`_^~' " ??
* From experiment in DOSWindows, "*+=|\[];:\",<>.?/" are illegal.
* See IBM DOS4.0 Tech Ref. B-57.
*/
if ((c >= 'A') && (c <= 'Z')) {
} else if ((c >= '0') && (c <= '9')) {
} else {
charp = valid_chars;
if (c == *charp) {
}
charp++;
}
}
return (is_valid);
}
static int
dos_label_char(int c)
{
int return_char;
if (isalnum(c)) {
return_char = c;
} else if (isspace(c)) {
return_char = '_';
} else {
switch (c) {
case '.':
case '_':
case '+':
return_char = c;
break;
default:
return_char = NULLC;
}
}
return (return_char);
}
static char *
{
return (NULL);
}
return (NULL);
}
return (NULL);
}
dir_index = 0;
/*
* Lint complains about the cast below,
* but there's no alignment problem.
*/
(dir_index < num_entries)) {
}
dir_index++;
/*
* Lint complains about the cast below,
* but there's no alignment problem.
*/
sizeof (struct pcdir)];
}
return (volname);
}
static enum laread_res
{
unsigned long fat_offset;
unsigned long fat_sec_off; /* offset of FAT sector */
unsigned int fat_sub_off; /* offset within sector */
int read_length;
return (L_ERROR);
}
if (read_length != DOS_READ_LENGTH) {
return (L_UNFORMATTED);
}
return (L_UNRECOG);
}
if (fat_offset >= sizeof (dos_buf)) {
return (L_ERROR);
}
if (read_length != DOS_READ_LENGTH) {
return (L_UNRECOG);
}
return (L_UNRECOG);
}
return (L_UNRECOG);
}
DOS_OEM_LENGTH) == 0) {
return (L_NOTUNIQUE);
}
return (L_NOTUNIQUE);
} else if (dos_magic == 0) {
"find_dos_label(): seek failed; %m\n"));
return (L_NOTUNIQUE);
}
"find_dos_label: couldn't write back label; %m\n"));
return (L_NOTUNIQUE);
}
}
return (L_FOUND);
}
static bool_t
{
struct mboot *master_boot_recordp;
int partition_index;
struct ipart *partitionp;
int read_length;
if ((read_length) != DOS_READ_LENGTH) {
return (FALSE);
}
/*
* Lint complains about the cast below,
* but there's no alignment problem.
*/
debug(3,
"find_fdisk_partition: DOS magic %X AFU (%X expected)\n",
return (FALSE);
}
partition_index = 0;
while ((partition_index < FD_NUMPART) &&
(no_solaris_partition == TRUE)) {
/*
* Lint complains about the cast below,
* but there's no alignment problem.
*/
partitionp = (struct ipart *)
sizeof (struct ipart)]);
}
}
if (no_solaris_partition == FALSE) {
}
return (found);
}
static void
{
int index;
int offset;
char test_char;
char *volnamep;
index = 0;
index++;
offset++;
}
index--;
}
} else {
}
}
}