patch-2.1.103 linux/fs/umsdos/mangle.c
Next file: linux/fs/umsdos/namei.c
Previous file: linux/fs/umsdos/ioctl.c
Back to the patch index
Back to the overall index
- Lines: 949
- Date:
Tue May 19 15:06:49 1998
- Orig file:
v2.1.102/linux/fs/umsdos/mangle.c
- Orig date:
Tue Feb 17 13:12:48 1998
diff -u --recursive --new-file v2.1.102/linux/fs/umsdos/mangle.c linux/fs/umsdos/mangle.c
@@ -1,7 +1,7 @@
/*
* linux/fs/umsdos/mangle.c
*
- * Written 1993 by Jacques Gelinas
+ * Written 1993 by Jacques Gelinas
*
* Control the mangling of file name to fit msdos name space.
* Many optimisation by GLU == dglaude@is1.vub.ac.be (GLAUDE DAVID)
@@ -13,474 +13,507 @@
#include <linux/umsdos_fs.h>
/*
- Complete the mangling of the MSDOS fake name
- based on the position of the entry in the EMD file.
-
- Simply complete the job of umsdos_parse; fill the extension.
-
- Beware that info->f_pos must be set.
-*/
+ * Complete the mangling of the MSDOS fake name
+ * based on the position of the entry in the EMD file.
+ *
+ * Simply complete the job of umsdos_parse; fill the extension.
+ *
+ * Beware that info->f_pos must be set.
+ */
void umsdos_manglename (struct umsdos_info *info)
{
- if (info->msdos_reject){
- /* #Specification: file name / non MSDOS conforming / mangling
- Each non MSDOS conforming file has a special extension
- build from the entry position in the EMD file.
-
- This number is then transform in a base 32 number, where
- each digit is expressed like hexadecimal number, using
- digit and letter, except it uses 22 letters from 'a' to 'v'.
- The number 32 comes from 2**5. It is faster to split a binary
- number using a base which is a power of two. And I was 32
- when I started this project. Pick your answer :-) .
-
- If the result is '0', it is replace with '_', simply
- to make it odd.
-
- This is true for the first two character of the extension.
- The last one is taken from a list of odd character, which
- are:
-
- { } ( ) ! ` ^ & @
-
- With this scheme, we can produce 9216 ( 9* 32 * 32)
- different extensions which should not clash with any useful
- extension already popular or meaningful. Since most directory
- have much less than 32 * 32 files in it, the first character
- of the extension of any mangle name will be {.
-
- Here are the reason to do this (this kind of mangling).
-
- -The mangling is deterministic. Just by the extension, we
- are able to locate the entry in the EMD file.
-
- -By keeping to beginning of the file name almost unchanged,
- we are helping the MSDOS user.
-
- -The mangling produces names not too ugly, so an msdos user
- may live with it (remember it, type it, etc...).
-
- -The mangling produces names ugly enough so no one will
- ever think of using such a name in real life. This is not
- fool proof. I don't think there is a total solution to this.
- */
- union {
- int entry_num;
- struct {
- unsigned num1:5,num2:5,num3:5;
- }num;
- } u;
- char *pt = info->fake.fname + info->fake.len;
- /* lookup for encoding the last character of the extension */
- /* It contain valid character after the ugly one to make sure */
- /* even if someone overflow the 32 * 32 * 9 limit, it still do */
- /* something */
+ if (info->msdos_reject) {
+ /* #Specification: file name / non MSDOS conforming / mangling
+ * Each non MSDOS conforming file has a special extension
+ * build from the entry position in the EMD file.
+ *
+ * This number is then transform in a base 32 number, where
+ * each digit is expressed like hexadecimal number, using
+ * digit and letter, except it uses 22 letters from 'a' to 'v'.
+ * The number 32 comes from 2**5. It is faster to split a binary
+ * number using a base which is a power of two. And I was 32
+ * when I started this project. Pick your answer :-) .
+ *
+ * If the result is '0', it is replace with '_', simply
+ * to make it odd.
+ *
+ * This is true for the first two character of the extension.
+ * The last one is taken from a list of odd character, which
+ * are:
+ *
+ * { } ( ) ! ` ^ & @
+ *
+ * With this scheme, we can produce 9216 ( 9* 32 * 32)
+ * different extensions which should not clash with any useful
+ * extension already popular or meaningful. Since most directory
+ * have much less than 32 * 32 files in it, the first character
+ * of the extension of any mangle name will be {.
+ *
+ * Here are the reason to do this (this kind of mangling).
+ *
+ * -The mangling is deterministic. Just by the extension, we
+ * are able to locate the entry in the EMD file.
+ *
+ * -By keeping to beginning of the file name almost unchanged,
+ * we are helping the MSDOS user.
+ *
+ * -The mangling produces names not too ugly, so an msdos user
+ * may live with it (remember it, type it, etc...).
+ *
+ * -The mangling produces names ugly enough so no one will
+ * ever think of using such a name in real life. This is not
+ * fool proof. I don't think there is a total solution to this.
+ */
+ union {
+ int entry_num;
+ struct {
+ unsigned num1:5, num2:5, num3:5;
+ } num;
+ } u;
+ char *pt = info->fake.fname + info->fake.len;
+
+ /* lookup for encoding the last character of the extension */
+ /* It contain valid character after the ugly one to make sure */
+ /* even if someone overflow the 32 * 32 * 9 limit, it still do */
+ /* something */
#define SPECIAL_MANGLING '{','}','(',')','!','`','^','&','@'
- static char lookup3[]={
- SPECIAL_MANGLING,
- /* This is the start of lookup12 */
- '_','1','2','3','4','5','6','7','8','9',
- 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o',
- 'p','q','r','s','t','u','v'
- };
+ static char lookup3[] =
+ {
+ SPECIAL_MANGLING,
+ /* This is the start of lookup12 */
+ '_', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
+ 'p', 'q', 'r', 's', 't', 'u', 'v'
+ };
+
#define lookup12 (lookup3+9)
- u.entry_num = info->f_pos / UMSDOS_REC_SIZE;
- if (u.entry_num > (9* 32 * 32)){
- printk ("UMSDOS: More than 9216 file in a directory.\n"
- "This may break the mangling strategy.\n"
- "Not a killer problem. See doc.\n");
- }
- *pt++ = '.';
- *pt++ = lookup3 [u.num.num3];
- *pt++ = lookup12[u.num.num2];
- *pt++ = lookup12[u.num.num1];
- *pt = '\0'; /* help doing printk */
- info->fake.len += 4;
- info->msdos_reject = 0; /* Avoid mangling twice */
- }
+ u.entry_num = info->f_pos / UMSDOS_REC_SIZE;
+ if (u.entry_num > (9 * 32 * 32)) {
+ printk ("UMSDOS: More than 9216 file in a directory.\n"
+ "This may break the mangling strategy.\n"
+ "Not a killer problem. See doc.\n");
+ }
+ *pt++ = '.';
+ *pt++ = lookup3[u.num.num3];
+ *pt++ = lookup12[u.num.num2];
+ *pt++ = lookup12[u.num.num1];
+ *pt = '\0'; /* help doing printk */
+ info->fake.len += 4;
+ info->msdos_reject = 0; /* Avoid mangling twice */
+ }
}
/*
- Evaluate the record size needed to store of name of len character.
- The value returned is a multiple of UMSDOS_REC_SIZE.
-*/
+ * Evaluate the record size needed to store of name of len character.
+ * The value returned is a multiple of UMSDOS_REC_SIZE.
+ */
int umsdos_evalrecsize (int len)
{
- struct umsdos_dirent dirent;
- int nbrec = 1+((len-1+(dirent.name-(char*)&dirent))
- / UMSDOS_REC_SIZE);
- return nbrec * UMSDOS_REC_SIZE;
- /*
- GLU This should be inlined or something to speed it up to the max.
- GLU nbrec is absolutely not needed to return the value.
- */
+ struct umsdos_dirent dirent;
+ int nbrec = 1 + ((len - 1 + (dirent.name - (char *) &dirent))
+ / UMSDOS_REC_SIZE);
+
+ return nbrec * UMSDOS_REC_SIZE;
+ /*
+ * GLU This should be inlined or something to speed it up to the max.
+ * GLU nbrec is absolutely not needed to return the value.
+ */
}
#ifdef TEST
int umsdos_evalrecsize_old (int len)
{
- struct umsdos_dirent dirent;
- int size = len + (dirent.name-(char*)&dirent);
- int nbrec = size / UMSDOS_REC_SIZE;
- int extra = size % UMSDOS_REC_SIZE;
- if (extra > 0) nbrec++;
- return nbrec * UMSDOS_REC_SIZE;
+ struct umsdos_dirent dirent;
+ int size = len + (dirent.name - (char *) &dirent);
+ int nbrec = size / UMSDOS_REC_SIZE;
+ int extra = size % UMSDOS_REC_SIZE;
+
+ if (extra > 0)
+ nbrec++;
+ return nbrec * UMSDOS_REC_SIZE;
}
#endif
/*
- Fill the struct info with the full and msdos name of a file
- Return 0 if all is ok, a negative error code otherwise.
-*/
+ * Fill the struct info with the full and msdos name of a file
+ * Return 0 if all is ok, a negative error code otherwise.
+ */
int umsdos_parse (
- const char *fname,
- int len,
- struct umsdos_info *info)
+ const char *fname,
+ int len,
+ struct umsdos_info *info)
{
- int ret = -ENAMETOOLONG;
- /* #Specification: file name / too long
- If a file name exceed UMSDOS maxima, the file name is silently
- truncated. This makes it conformant with the other file system
- of Linux (minix and ext2 at least).
- */
- if (len > UMSDOS_MAXNAME) len = UMSDOS_MAXNAME;
- {
- const char *firstpt=NULL; /* First place we saw a . in fname */
- /* #Specification: file name / non MSDOS conforming / base length 0
- file name beginning with a period '.' are invalid for MsDOS.
- It needs absolutely a base name. So the file name is mangled
- */
- int ivldchar = fname[0] == '.';/* At least one invalid character */
- int msdos_len = len;
- int base_len;
- /*
- cardinal_per_size tells if there exist at least one
- DOS pseudo devices on length n. See the test below.
- */
- static const char cardinal_per_size[9]={
- 0, 0, 0, 1, 1, 0, 1, 0, 1
- };
- /*
- lkp translate all character to acceptable character (for DOS).
- When lkp[n] == n, it means also it is an acceptable one.
- So it serve both as a flag and as a translator.
- */
- static char lkp[256];
- static char is_init=0;
- if (!is_init){
- /*
- Initialisation of the array is easier and less error prone
- like this.
- */
- int i;
- static const char *spc = "\"*+,/:;<=>?[\\]|~";
- is_init = 1;
- for (i=0; i<=32; i++) lkp[i] = '#';
- for (i=33; i<'A'; i++) lkp[i] = (char)i;
- for (i='A'; i<='Z'; i++) lkp[i] = (char)(i+('a'-'A'));
- for (i='Z'+1; i<127; i++) lkp[i] = (char)i;
- for (i=128; i<256; i++) lkp[i] = '#';
-
- lkp['.'] = '_';
- while (*spc != '\0') lkp[(unsigned char)(*spc++)] = '#';
- }
- /* GLU
- file name which are longer than 8+'.'+3 are invalid for MsDOS.
- So the file name is to be mangled no more test needed.
- This Speed Up for long and very long name.
- The position of the last point is no more necessary anyway.
- */
- if (len<=(8+1+3)){
- const char *pt = fname;
- const char *endpt = fname + len;
- while (pt < endpt){
- if (*pt == '.'){
- if (firstpt != NULL){
- /* 2 . in a file name. Reject */
- ivldchar = 1;
- break;
- }else{
- int extlen = (int)(endpt - pt);
- firstpt = pt;
- if (firstpt - fname > 8){
- /* base name longer than 8: reject */
- ivldchar = 1;
- break;
- }else if (extlen > 4){
- /* Extension longer than 4 (including .): reject */
- ivldchar = 1;
- break;
- }else if (extlen == 1){
- /* #Specification: file name / non MSDOS conforming / last char == .
- If the last character of a file name is
- a period, mangling is applied. MsDOS do
- not support those file name.
- */
- ivldchar = 1;
- break;
- }else if (extlen == 4){
- /* #Specification: file name / non MSDOS conforming / mangling clash
- To avoid clash with the umsdos mangling, any file
- with a special character as the first character
- of the extension will be mangled. This solve the
- following problem:
-
- #
- touch FILE
- # FILE is invalid for DOS, so mangling is applied
- # file.{_1 is created in the DOS directory
- touch file.{_1
- # To UMSDOS file point to a single DOS entry.
- # So file.{_1 has to be mangled.
- #
- */
- static char special[]={
- SPECIAL_MANGLING,'\0'
- };
- if (strchr(special,firstpt[1])!= NULL){
- ivldchar = 1;
- break;
- }
- }
- }
- }else if (lkp[(unsigned char)(*pt)] != *pt){
- ivldchar = 1;
- break;
- }
- pt++;
- }
- }else{
- ivldchar = 1;
- }
- if (ivldchar
- || (firstpt == NULL && len > 8)
- || (len == UMSDOS_EMD_NAMELEN
- && memcmp(fname,UMSDOS_EMD_FILE,UMSDOS_EMD_NAMELEN)==0)){
- /* #Specification: file name / --linux-.---
- The name of the EMD file --linux-.--- is map to a mangled
- name. So UMSDOS does not restrict its use.
- */
- /* #Specification: file name / non MSDOS conforming / mangling
- Non MSDOS conforming file name must use some alias to fit
- in the MSDOS name space.
-
- The strategy is simple. The name is simply truncated to
- 8 char. points are replace with underscore and a
- number is given as an extension. This number correspond
- to the entry number in the EMD file. The EMD file
- only need to carry the real name.
-
- Upper case is also convert to lower case.
- Control character are converted to #.
- Space are converted to #.
- The following character are also converted to #.
- #
- " * + , / : ; < = > ? [ \ ] | ~
- #
-
- Sometime, the problem is not in MsDOS itself but in
- command.com.
- */
- int i;
- char *pt = info->fake.fname;
- base_len = msdos_len = (msdos_len>8) ? 8 : msdos_len;
- /*
- There is no '.' any more so we know for a fact that
- the base length is the length.
- */
- memcpy (info->fake.fname,fname,msdos_len);
- for (i=0; i<msdos_len; i++, pt++) *pt = lkp[(unsigned char)(*pt)];
- *pt = '\0'; /* GLU C'est sur on a un 0 a la fin */
- info->msdos_reject = 1;
- /*
- The numeric extension is added only when we know
- the position in the EMD file, in umsdos_newentry(),
- umsdos_delentry(), and umsdos_findentry().
- See umsdos_manglename().
- */
- }else{
- /* Conforming MSDOS file name */
- strncpy (info->fake.fname,fname,len);
- info->msdos_reject = 0;
- base_len = firstpt != NULL ? (int)(firstpt - fname) : len;
- }
- if (cardinal_per_size[base_len]){
- /* #Specification: file name / MSDOS devices / mangling
- To avoid unreachable file from MsDOS, any MsDOS conforming
- file with a basename equal to one of the MsDOS pseudo
- devices will be mangled.
-
- If a file such as "prn" was created, it would be unreachable
- under MsDOS because prn is assumed to be the printer, even
- if the file does have an extension.
-
- Since the extension is unimportant to MsDOS, we must patch
- the basename also. We simply insert a minus '-'. To avoid
- conflict with valid file with a minus in front (such as
- "-prn"), we add an mangled extension like any other
- mangled file name.
-
- Here is the list of DOS pseudo devices:
-
- #
- "prn","con","aux","nul",
- "lpt1","lpt2","lpt3","lpt4",
- "com1","com2","com3","com4",
- "clock$"
- #
-
- and some standard ones for common DOS programs
-
- "emmxxxx0","xmsxxxx0","setverxx"
-
- (Thanks to Chris Hall <CAH17@PHOENIX.CAMBRIDGE.AC.UK>
- for pointing these to me).
-
- Is there one missing ?
- */
- /* This table must be ordered by length */
- static const char *tbdev[]={
- "prn","con","aux","nul",
- "lpt1","lpt2","lpt3","lpt4",
- "com1","com2","com3","com4",
- "clock$",
- "emmxxxx0","xmsxxxx0","setverxx"
- };
- /* Tell where to find in tbdev[], the first name of */
- /* a certain length */
- static const char start_ind_dev[9]={
- 0, 0, 0, 4, 12, 12, 13, 13, 16
- };
- char basen[9];
- int i;
- for (i=start_ind_dev[base_len-1]; i<start_ind_dev[base_len]; i++){
- if (memcmp(info->fake.fname,tbdev[i],base_len)==0){
- memcpy (basen,info->fake.fname,base_len);
- basen[base_len] = '\0'; /* GLU C'est sur on a un 0 a la fin */
- /*
- GLU On ne fait cela que si necessaire, on essaye d'etre le
- GLU simple dans le cas general (le plus frequent).
- */
- info->fake.fname[0] = '-';
- strcpy (info->fake.fname+1,basen); /* GLU C'est sur on a un 0 a la fin */
- msdos_len = (base_len==8) ? 8 : base_len + 1;
- info->msdos_reject = 1;
- break;
+ int ret = -ENAMETOOLONG;
+
+ /* #Specification: file name / too long
+ * If a file name exceed UMSDOS maxima, the file name is silently
+ * truncated. This makes it conformant with the other file system
+ * of Linux (minix and ext2 at least).
+ */
+ if (len > UMSDOS_MAXNAME)
+ len = UMSDOS_MAXNAME;
+ {
+ const char *firstpt = NULL; /* First place we saw a . in fname */
+
+ /* #Specification: file name / non MSDOS conforming / base length 0
+ * file name beginning with a period '.' are invalid for MsDOS.
+ * It needs absolutely a base name. So the file name is mangled
+ */
+ int ivldchar = fname[0] == '.'; /* At least one invalid character */
+ int msdos_len = len;
+ int base_len;
+
+ /*
+ * cardinal_per_size tells if there exist at least one
+ * DOS pseudo devices on length n. See the test below.
+ */
+ static const char cardinal_per_size[9] =
+ {
+ 0, 0, 0, 1, 1, 0, 1, 0, 1
+ };
+
+ /*
+ * lkp translate all character to acceptable character (for DOS).
+ * When lkp[n] == n, it means also it is an acceptable one.
+ * So it serve both as a flag and as a translator.
+ */
+ static char lkp[256];
+ static char is_init = 0;
+
+ if (!is_init) {
+ /*
+ * Initialisation of the array is easier and less error prone
+ * like this.
+ */
+ int i;
+ static const char *spc = "\"*+,/:;<=>?[\\]|~";
+
+ is_init = 1;
+ for (i = 0; i <= 32; i++)
+ lkp[i] = '#';
+ for (i = 33; i < 'A'; i++)
+ lkp[i] = (char) i;
+ for (i = 'A'; i <= 'Z'; i++)
+ lkp[i] = (char) (i + ('a' - 'A'));
+ for (i = 'Z' + 1; i < 127; i++)
+ lkp[i] = (char) i;
+ for (i = 128; i < 256; i++)
+ lkp[i] = '#';
+
+ lkp['.'] = '_';
+ while (*spc != '\0')
+ lkp[(unsigned char) (*spc++)] = '#';
+ }
+ /* GLU
+ * file name which are longer than 8+'.'+3 are invalid for MsDOS.
+ * So the file name is to be mangled no more test needed.
+ * This Speed Up for long and very long name.
+ * The position of the last point is no more necessary anyway.
+ */
+ if (len <= (8 + 1 + 3)) {
+ const char *pt = fname;
+ const char *endpt = fname + len;
+
+ while (pt < endpt) {
+ if (*pt == '.') {
+ if (firstpt != NULL) {
+ /* 2 . in a file name. Reject */
+ ivldchar = 1;
+ break;
+ } else {
+ int extlen = (int) (endpt - pt);
+
+ firstpt = pt;
+ if (firstpt - fname > 8) {
+ /* base name longer than 8: reject */
+ ivldchar = 1;
+ break;
+ } else if (extlen > 4) {
+ /* Extension longer than 4 (including .): reject */
+ ivldchar = 1;
+ break;
+ } else if (extlen == 1) {
+ /* #Specification: file name / non MSDOS conforming / last char == .
+ * If the last character of a file name is
+ * a period, mangling is applied. MsDOS do
+ * not support those file name.
+ */
+ ivldchar = 1;
+ break;
+ } else if (extlen == 4) {
+ /* #Specification: file name / non MSDOS conforming / mangling clash
+ * To avoid clash with the umsdos mangling, any file
+ * with a special character as the first character
+ * of the extension will be mangled. This solve the
+ * following problem:
+ *
+ * #
+ * touch FILE
+ * # FILE is invalid for DOS, so mangling is applied
+ * # file.{_1 is created in the DOS directory
+ * touch file.{_1
+ * # To UMSDOS file point to a single DOS entry.
+ * # So file.{_1 has to be mangled.
+ * #
+ */
+ static char special[] =
+ {
+ SPECIAL_MANGLING, '\0'
+ };
+
+ if (strchr (special, firstpt[1]) != NULL) {
+ ivldchar = 1;
+ break;
+ }
+ }
+ }
+ } else if (lkp[(unsigned char) (*pt)] != *pt) {
+ ivldchar = 1;
+ break;
+ }
+ pt++;
+ }
+ } else {
+ ivldchar = 1;
+ }
+ if (ivldchar
+ || (firstpt == NULL && len > 8)
+ || (len == UMSDOS_EMD_NAMELEN
+ && memcmp (fname, UMSDOS_EMD_FILE, UMSDOS_EMD_NAMELEN) == 0)) {
+ /* #Specification: file name / --linux-.---
+ * The name of the EMD file --linux-.--- is map to a mangled
+ * name. So UMSDOS does not restrict its use.
+ */
+ /* #Specification: file name / non MSDOS conforming / mangling
+ * Non MSDOS conforming file name must use some alias to fit
+ * in the MSDOS name space.
+ *
+ * The strategy is simple. The name is simply truncated to
+ * 8 char. points are replace with underscore and a
+ * number is given as an extension. This number correspond
+ * to the entry number in the EMD file. The EMD file
+ * only need to carry the real name.
+ *
+ * Upper case is also convert to lower case.
+ * Control character are converted to #.
+ * Space are converted to #.
+ * The following character are also converted to #.
+ * #
+ * " * + , / : ; < = > ? [ \ ] | ~
+ * #
+ *
+ * Sometime, the problem is not in MsDOS itself but in
+ * command.com.
+ */
+ int i;
+ char *pt = info->fake.fname;
+
+ base_len = msdos_len = (msdos_len > 8) ? 8 : msdos_len;
+ /*
+ * There is no '.' any more so we know for a fact that
+ * the base length is the length.
+ */
+ memcpy (info->fake.fname, fname, msdos_len);
+ for (i = 0; i < msdos_len; i++, pt++)
+ *pt = lkp[(unsigned char) (*pt)];
+ *pt = '\0'; /* GLU C'est sur on a un 0 a la fin */
+ info->msdos_reject = 1;
+ /*
+ * The numeric extension is added only when we know
+ * the position in the EMD file, in umsdos_newentry(),
+ * umsdos_delentry(), and umsdos_findentry().
+ * See umsdos_manglename().
+ */
+ } else {
+ /* Conforming MSDOS file name */
+ strncpy (info->fake.fname, fname, len);
+ info->msdos_reject = 0;
+ base_len = firstpt != NULL ? (int) (firstpt - fname) : len;
+ }
+ if (cardinal_per_size[base_len]) {
+ /* #Specification: file name / MSDOS devices / mangling
+ * To avoid unreachable file from MsDOS, any MsDOS conforming
+ * file with a basename equal to one of the MsDOS pseudo
+ * devices will be mangled.
+ *
+ * If a file such as "prn" was created, it would be unreachable
+ * under MsDOS because prn is assumed to be the printer, even
+ * if the file does have an extension.
+ *
+ * Since the extension is unimportant to MsDOS, we must patch
+ * the basename also. We simply insert a minus '-'. To avoid
+ * conflict with valid file with a minus in front (such as
+ * "-prn"), we add an mangled extension like any other
+ * mangled file name.
+ *
+ * Here is the list of DOS pseudo devices:
+ *
+ * #
+ * "prn","con","aux","nul",
+ * "lpt1","lpt2","lpt3","lpt4",
+ * "com1","com2","com3","com4",
+ * "clock$"
+ * #
+ *
+ * and some standard ones for common DOS programs
+ *
+ * "emmxxxx0","xmsxxxx0","setverxx"
+ *
+ * (Thanks to Chris Hall <CAH17@PHOENIX.CAMBRIDGE.AC.UK>
+ * for pointing these to me).
+ *
+ * Is there one missing ?
+ */
+ /* This table must be ordered by length */
+ static const char *tbdev[] =
+ {
+ "prn", "con", "aux", "nul",
+ "lpt1", "lpt2", "lpt3", "lpt4",
+ "com1", "com2", "com3", "com4",
+ "clock$",
+ "emmxxxx0", "xmsxxxx0", "setverxx"
+ };
+
+ /* Tell where to find in tbdev[], the first name of */
+ /* a certain length */
+ static const char start_ind_dev[9] =
+ {
+ 0, 0, 0, 4, 12, 12, 13, 13, 16
+ };
+ char basen[9];
+ int i;
+
+ for (i = start_ind_dev[base_len - 1]; i < start_ind_dev[base_len]; i++) {
+ if (memcmp (info->fake.fname, tbdev[i], base_len) == 0) {
+ memcpy (basen, info->fake.fname, base_len);
+ basen[base_len] = '\0'; /* GLU C'est sur on a un 0 a la fin */
+ /*
+ * GLU On ne fait cela que si necessaire, on essaye d'etre le
+ * GLU simple dans le cas general (le plus frequent).
+ */
+ info->fake.fname[0] = '-';
+ strcpy (info->fake.fname + 1, basen); /* GLU C'est sur on a un 0 a la fin */
+ msdos_len = (base_len == 8) ? 8 : base_len + 1;
+ info->msdos_reject = 1;
+ break;
+ }
+ }
+ }
+ info->fake.fname[msdos_len] = '\0'; /* Help doing printk */
+ /* GLU Ce zero devrais deja y etre ! (invariant ?) */
+ info->fake.len = msdos_len;
+ /* Pourquoi ne pas utiliser info->fake.len partout ??? plus long ? */
+ memcpy (info->entry.name, fname, len);
+ info->entry.name_len = len;
+ ret = 0;
}
- }
- }
- info->fake.fname[msdos_len] = '\0'; /* Help doing printk */
- /* GLU Ce zero devrais deja y etre ! (invariant ?) */
- info->fake.len = msdos_len;
- /* Pourquoi ne pas utiliser info->fake.len partout ??? plus long ?*/
- memcpy (info->entry.name,fname,len);
- info->entry.name_len = len;
- ret = 0;
- }
- /*
- Evaluate how many record are needed to store this entry.
- */
- info->recsize = umsdos_evalrecsize (len);
- return ret;
+ /*
+ * Evaluate how many record are needed to store this entry.
+ */
+ info->recsize = umsdos_evalrecsize (len);
+ return ret;
}
#ifdef TEST
-struct MANG_TEST{
- char *fname; /* Name to validate */
- int msdos_reject; /* Expected msdos_reject flag */
- char *msname; /* Expected msdos name */
+struct MANG_TEST {
+ char *fname; /* Name to validate */
+ int msdos_reject; /* Expected msdos_reject flag */
+ char *msname; /* Expected msdos name */
};
-struct MANG_TEST tb[]={
- "hello", 0, "hello",
- "hello.1", 0, "hello.1",
- "hello.1_", 0, "hello.1_",
- "prm", 0, "prm",
-
+struct MANG_TEST tb[] =
+{
+ "hello", 0, "hello",
+ "hello.1", 0, "hello.1",
+ "hello.1_", 0, "hello.1_",
+ "prm", 0, "prm",
+
#ifdef PROPOSITION
- "HELLO", 1, "hello",
- "Hello.1", 1, "hello.1",
- "Hello.c", 1, "hello.c",
+ "HELLO", 1, "hello",
+ "Hello.1", 1, "hello.1",
+ "Hello.c", 1, "hello.c",
#elseif
/*
- Je trouve les trois exemples ci-dessous tres "malheureux".
- Je propose de mettre en minuscule dans un passe preliminaire,
- et de tester apres si il y a d'autres caracters "mechants".
- Bon, je ne l'ai pas fait, parceque ce n'est pas si facilement
- modifiable que ca. Mais c'est pour le principe.
- Evidemment cela augmente les chances de "Collision",
- par exemple: entre "HELLO" et "Hello", mais ces problemes
- peuvent etre traiter ailleur avec les autres collisions.
-*/
- "HELLO", 1, "hello",
- "Hello.1", 1, "hello_1",
- "Hello.c", 1, "hello_c",
+ * Je trouve les trois exemples ci-dessous tres "malheureux".
+ * Je propose de mettre en minuscule dans un passe preliminaire,
+ * et de tester apres si il y a d'autres caracters "mechants".
+ * Bon, je ne l'ai pas fait, parceque ce n'est pas si facilement
+ * modifiable que ca. Mais c'est pour le principe.
+ * Evidemment cela augmente les chances de "Collision",
+ * par exemple: entre "HELLO" et "Hello", mais ces problemes
+ * peuvent etre traiter ailleur avec les autres collisions.
+ */
+ "HELLO", 1, "hello",
+ "Hello.1", 1, "hello_1",
+ "Hello.c", 1, "hello_c",
#endif
-
- "hello.{_1", 1, "hello_{_",
- "hello\t", 1, "hello#",
- "hello.1.1", 1, "hello_1_",
- "hel,lo", 1, "hel#lo",
- "Salut.Tu.vas.bien?", 1, "salut_tu",
- ".profile", 1, "_profile",
- ".xv", 1, "_xv",
- "toto.", 1, "toto_",
- "clock$.x", 1, "-clock$",
- "emmxxxx0", 1, "-emmxxxx",
- "emmxxxx0.abcd", 1, "-emmxxxx",
- "aux", 1, "-aux",
- "prn", 1, "-prn",
- "prn.abc", 1, "-prn",
- "PRN", 1, "-prn",
+
+ "hello.{_1", 1, "hello_{_",
+ "hello\t", 1, "hello#",
+ "hello.1.1", 1, "hello_1_",
+ "hel,lo", 1, "hel#lo",
+ "Salut.Tu.vas.bien?", 1, "salut_tu",
+ ".profile", 1, "_profile",
+ ".xv", 1, "_xv",
+ "toto.", 1, "toto_",
+ "clock$.x", 1, "-clock$",
+ "emmxxxx0", 1, "-emmxxxx",
+ "emmxxxx0.abcd", 1, "-emmxxxx",
+ "aux", 1, "-aux",
+ "prn", 1, "-prn",
+ "prn.abc", 1, "-prn",
+ "PRN", 1, "-prn",
/*
- GLU ATTENTION : Le resultat de ceux-ci sont differents avec ma version
- GLU du mangle par rapport au mangle originale.
- GLU CAUSE: La maniere de calculer la variable baselen.
- GLU Pour toi c'est toujours 3
- GLU Pour moi c'est respectivement 7, 8 et 8
- */
- "PRN.abc", 1, "prn_abc",
- "Prn.abcd", 1, "prn_abcd",
- "prn.abcd", 1, "prn_abcd",
- "Prn.abcdefghij", 1, "prn_abcd"
+ * GLU ATTENTION : Le resultat de ceux-ci sont differents avec ma version
+ * GLU du mangle par rapport au mangle originale.
+ * GLU CAUSE: La maniere de calculer la variable baselen.
+ * GLU Pour toi c'est toujours 3
+ * GLU Pour moi c'est respectivement 7, 8 et 8
+ */
+ "PRN.abc", 1, "prn_abc",
+ "Prn.abcd", 1, "prn_abcd",
+ "prn.abcd", 1, "prn_abcd",
+ "Prn.abcdefghij", 1, "prn_abcd"
};
int main (int argc, char *argv[])
{
- int i,rold,rnew;
- printf ("Testing the umsdos_parse.\n");
- for (i=0; i<sizeof(tb)/sizeof(tb[0]); i++){
- struct MANG_TEST *pttb = tb+i;
- struct umsdos_info info;
- int ok = umsdos_parse (pttb->fname,strlen(pttb->fname),&info);
- if (strcmp(info.fake.fname,pttb->msname)!=0){
- printf ("**** %s -> ",pttb->fname);
- printf ("%s <> %s\n",info.fake.fname,pttb->msname);
- }else if (info.msdos_reject != pttb->msdos_reject){
- printf ("**** %s -> %s ",pttb->fname,pttb->msname);
- printf ("%d <> %d\n",info.msdos_reject,pttb->msdos_reject);
- }else{
- printf (" %s -> %s %d\n",pttb->fname,pttb->msname
- ,pttb->msdos_reject);
- }
- }
- printf ("Testing the new umsdos_evalrecsize.");
- for (i=0; i<UMSDOS_MAXNAME ; i++){
- rnew=umsdos_evalrecsize (i);
- rold=umsdos_evalrecsize_old (i);
- if (!(i%UMSDOS_REC_SIZE)){
- printf ("\n%d:\t",i);
- }
- if (rnew!=rold){
- printf ("**** %d newres: %d != %d \n", i, rnew, rold);
- }else{
- printf(".");
- }
- }
- printf ("\nEnd of Testing.\n");
-
- return 0;
+ int i, rold, rnew;
+
+ printf ("Testing the umsdos_parse.\n");
+ for (i = 0; i < sizeof (tb) / sizeof (tb[0]); i++) {
+ struct MANG_TEST *pttb = tb + i;
+ struct umsdos_info info;
+ int ok = umsdos_parse (pttb->fname, strlen (pttb->fname), &info);
+
+ if (strcmp (info.fake.fname, pttb->msname) != 0) {
+ printf ("**** %s -> ", pttb->fname);
+ printf ("%s <> %s\n", info.fake.fname, pttb->msname);
+ } else if (info.msdos_reject != pttb->msdos_reject) {
+ printf ("**** %s -> %s ", pttb->fname, pttb->msname);
+ printf ("%d <> %d\n", info.msdos_reject, pttb->msdos_reject);
+ } else {
+ printf (" %s -> %s %d\n", pttb->fname, pttb->msname
+ ,pttb->msdos_reject);
+ }
+ }
+ printf ("Testing the new umsdos_evalrecsize.");
+ for (i = 0; i < UMSDOS_MAXNAME; i++) {
+ rnew = umsdos_evalrecsize (i);
+ rold = umsdos_evalrecsize_old (i);
+ if (!(i % UMSDOS_REC_SIZE)) {
+ printf ("\n%d:\t", i);
+ }
+ if (rnew != rold) {
+ printf ("**** %d newres: %d != %d \n", i, rnew, rold);
+ } else {
+ printf (".");
+ }
+ }
+ printf ("\nEnd of Testing.\n");
+
+ return 0;
}
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov