📄 mangle.c
字号:
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 names 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 converted to lower case. * Control character are converted to #. * Spaces are converted to #. * The following characters are also converted to #. * # * " * + , / : ; < = > ? [ \ ] | ~ * # * * Sometimes the problem is not in MS-DOS 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 We force null termination. */ 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 MS-DOS, any MS-DOS conforming * file with a basename equal to one of the MS-DOS pseudo * devices will be mangled. * * If a file such as "prn" was created, it would be unreachable * under MS-DOS because "prn" is assumed to be the printer, even * if the file does have an extension. * * Since the extension is unimportant to MS-DOS, 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 out 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 We force null termination. */ /* * GLU We do that only if necessary; we try to do the * GLU simple thing in the usual circumstance. */ info->fake.fname[0] = '-'; strcpy (info->fake.fname + 1, basen); /* GLU We already guaranteed a null would be at the end. */ msdos_len = (base_len == 8) ? 8 : base_len + 1; info->msdos_reject = 1; break; } } } info->fake.fname[msdos_len] = '\0'; /* Help doing printk */ /* GLU This zero should (always?) be there already. */ info->fake.len = msdos_len; /* Why not use info->fake.len everywhere? Is it longer? */ memcpy (info->entry.name, fname, len); info->entry.name[len] = '\0'; /* for printk */ info->entry.name_len = len; ret = 0; } /* * Evaluate how many records are needed to store this entry. */ info->recsize = umsdos_evalrecsize (len); return ret;}#ifdef TESTstruct 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",#ifdef PROPOSITION "HELLO", 1, "hello", "Hello.1", 1, "hello.1", "Hello.c", 1, "hello.c",#else/* * I find the three examples below very unfortunate. I propose to * convert them to lower case in a quick preliminary pass, then test * whether there are other troublesome characters. I have not made * this change, because it is not easy, but I wanted to mention the * principle. Obviously something like that would increase the chance * of collisions, for example between "HELLO" and "Hello", but these * can be treated elsewhere along with the other 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", /* * GLU WARNING: the results of these are different with my version * GLU of mangling compared to the original one. * GLU CAUSE: the manner of calculating the baselen variable. * GLU For you they are always 3. * GLU For me they are respectively 7, 8, and 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;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -