From 908b383ff43e05307ed1ec43cc2d6b0e67e3af19 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Aug 1996 12:34:10 +0000 Subject: [PATCH] added the validchars package written by tino@augsburg.net. This package automates the building of a "valid chars =" line for any client DOS based client. This makes setting things up right for european languages much easier. (This used to be commit d0ce245acca9ae5797ef9f5c770d1fcd2d7b3373) --- examples/validchars/msdos70.out | 257 +++++++++++++++++++++++++++++++ examples/validchars/nwdos70.out | 257 +++++++++++++++++++++++++++++++ examples/validchars/readme | 101 ++++++++++++ examples/validchars/validchr.c | 123 +++++++++++++++ examples/validchars/validchr.com | Bin 0 -> 9792 bytes 5 files changed, 738 insertions(+) create mode 100644 examples/validchars/msdos70.out create mode 100644 examples/validchars/nwdos70.out create mode 100644 examples/validchars/readme create mode 100644 examples/validchars/validchr.c create mode 100644 examples/validchars/validchr.com diff --git a/examples/validchars/msdos70.out b/examples/validchars/msdos70.out new file mode 100644 index 00000000000..a722b83604f --- /dev/null +++ b/examples/validchars/msdos70.out @@ -0,0 +1,257 @@ +255: ok +254: ok +253: ok +252: ok +251: ok +250: ok +249: ok +248: ok +247: ok +246: ok +245: ok +244: ok +243: ok +242: ok +241: ok +240: ok +239: ok +238: ok +237: ok +236: 237 +235: ok +234: ok +233: ok +232: ok +231: 232 +230: ok +229: ok +228: 229 +227: ok +226: ok +225: ok +224: ok +223: ok +222: ok +221: ok +220: ok +219: ok +218: ok +217: ok +216: ok +215: ok +214: ok +213: 73 +212: ok +211: ok +210: ok +209: ok +208: 209 +207: ok +206: ok +205: ok +204: ok +203: ok +202: ok +201: ok +200: ok +199: ok +198: 199 +197: ok +196: ok +195: ok +194: ok +193: ok +192: ok +191: ok +190: ok +189: ok +188: ok +187: ok +186: ok +185: ok +184: ok +183: ok +182: ok +181: ok +180: ok +179: ok +178: ok +177: ok +176: ok +175: ok +174: ok +173: ok +172: ok +171: ok +170: ok +169: ok +168: ok +167: ok +166: ok +165: ok +164: 165 +163: 233 +162: 224 +161: 214 +160: 181 +159: ok +158: ok +157: ok +156: ok +155: 157 +154: ok +153: ok +152: length 0 +151: 235 +150: 234 +149: 227 +148: 153 +147: 226 +146: ok +145: 146 +144: ok +143: ok +142: ok +141: 222 +140: 215 +139: 216 +138: 212 +137: 211 +136: 210 +135: 128 +134: 143 +133: 183 +132: 142 +131: 182 +130: 144 +129: 154 +128: ok +127: ok +126: ok +125: ok +124: open unlink 0 +123: ok +122: 90 +121: 89 +120: 88 +119: 87 +118: 86 +117: 85 +116: 84 +115: 83 +114: 82 +113: 81 +112: 80 +111: 79 +110: 78 +109: 77 +108: 76 +107: 75 +106: 74 +105: 73 +104: 72 +103: 71 +102: 70 +101: 69 +100: 68 +99: 67 +98: 66 +97: 65 +96: ok +95: ok +94: ok +93: open unlink 0 +92: open unlink 0 +91: open unlink 0 +90: ok +89: ok +88: ok +87: ok +86: ok +85: ok +84: ok +83: ok +82: ok +81: ok +80: ok +79: ok +78: ok +77: ok +76: ok +75: ok +74: ok +73: ok +72: ok +71: ok +70: ok +69: ok +68: ok +67: ok +66: ok +65: ok +64: ok +63: open unlink 0 +62: open unlink 0 +61: open unlink 0 +60: open unlink 0 +59: open unlink 0 +58: open unlink 0 +57: ok +56: ok +55: ok +54: ok +53: ok +52: ok +51: ok +50: ok +49: ok +48: ok +47: open unlink 0 +46: open unlink 0 +45: ok +44: open unlink 0 +43: open unlink 0 +42: open unlink 0 +41: ok +40: ok +39: ok +38: ok +37: ok +36: ok +35: ok +34: open unlink 0 +33: ok +32: open unlink 0 +31: open unlink 0 +30: open unlink 0 +29: open unlink 0 +28: open unlink 0 +27: open unlink 0 +26: open unlink 0 +25: open unlink 0 +24: open unlink 0 +23: open unlink 0 +22: open unlink 0 +21: open unlink 0 +20: open unlink 0 +19: open unlink 0 +18: open unlink 0 +17: open unlink 0 +16: open unlink 0 +15: open unlink 0 +14: open unlink 0 +13: open unlink 0 +12: open unlink 0 +11: open unlink 0 +10: open unlink 0 +9: open unlink 0 +8: open unlink 0 +7: open unlink 0 +6: open unlink 0 +5: open unlink 0 +4: open unlink 0 +3: open unlink 0 +2: open unlink 0 +1: open unlink 0 + + valid chars = 73:213 213:73 73:73 33 35 36 37 38 39 40 41 45 48 49 50 51 52 53 54 55 56 57 64 97:65 98:66 99:67 100:68 101:69 102:70 103:71 104:72 105:73 106:74 107:75 108:76 109:77 110:78 111:79 112:80 113:81 114:82 115:83 116:84 117:85 118:86 119:87 120:88 121:89 122:90 94 95 96 123 125 126 127 135:128 132:142 134:143 130:144 145:146 148:153 129:154 156 155:157 158 159 164:165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 160:181 131:182 133:183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198:199 200 201 202 203 204 205 206 207 208:209 136:210 137:211 138:212 161:214 140:215 139:216 217 218 219 220 221 141:222 223 162:224 225 147:226 149:227 228:229 230 231:232 163:233 150:234 151:235 236:237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 diff --git a/examples/validchars/nwdos70.out b/examples/validchars/nwdos70.out new file mode 100644 index 00000000000..b0dbf628531 --- /dev/null +++ b/examples/validchars/nwdos70.out @@ -0,0 +1,257 @@ +255: ok +254: ok +253: ok +252: ok +251: ok +250: ok +249: ok +248: ok +247: ok +246: ok +245: ok +244: ok +243: ok +242: ok +241: ok +240: ok +239: ok +238: ok +237: ok +236: ok +235: ok +234: ok +233: ok +232: ok +231: ok +230: ok +229: ok +228: ok +227: ok +226: ok +225: ok +224: ok +223: ok +222: ok +221: ok +220: ok +219: ok +218: ok +217: ok +216: ok +215: ok +214: ok +213: ok +212: ok +211: ok +210: ok +209: ok +208: ok +207: ok +206: ok +205: ok +204: ok +203: ok +202: ok +201: ok +200: ok +199: ok +198: ok +197: ok +196: ok +195: ok +194: ok +193: ok +192: ok +191: ok +190: ok +189: ok +188: ok +187: ok +186: ok +185: ok +184: ok +183: ok +182: ok +181: ok +180: ok +179: ok +178: ok +177: ok +176: ok +175: ok +174: ok +173: ok +172: ok +171: ok +170: ok +169: ok +168: ok +167: ok +166: ok +165: ok +164: 165 +163: 85 +162: 79 +161: 73 +160: 65 +159: ok +158: ok +157: ok +156: ok +155: ok +154: ok +153: ok +152: 89 +151: 85 +150: 85 +149: 79 +148: 153 +147: 79 +146: ok +145: 146 +144: ok +143: ok +142: ok +141: 73 +140: 73 +139: 73 +138: 69 +137: 69 +136: 69 +135: 128 +134: 143 +133: 65 +132: 142 +131: 65 +130: 69 +129: 154 +128: ok +127: ok +126: ok +125: ok +124: open unlink 0 +123: ok +122: 90 +121: 89 +120: 88 +119: 87 +118: 86 +117: 85 +116: 84 +115: 83 +114: 82 +113: 81 +112: 80 +111: 79 +110: 78 +109: 77 +108: 76 +107: 75 +106: 74 +105: 73 +104: 72 +103: 71 +102: 70 +101: 69 +100: 68 +99: 67 +98: 66 +97: 65 +96: ok +95: ok +94: ok +93: open unlink 0 +92: open unlink 0 +91: open unlink 0 +90: ok +89: ok +88: ok +87: ok +86: ok +85: ok +84: ok +83: ok +82: ok +81: ok +80: ok +79: ok +78: ok +77: ok +76: ok +75: ok +74: ok +73: ok +72: ok +71: ok +70: ok +69: ok +68: ok +67: ok +66: ok +65: ok +64: ok +63: open unlink 0 +62: open unlink 0 +61: open unlink 0 +60: open unlink 0 +59: open unlink 0 +58: open unlink 0 +57: ok +56: ok +55: ok +54: ok +53: ok +52: ok +51: ok +50: ok +49: ok +48: ok +47: open unlink 0 +46: open unlink 0 +45: ok +44: open unlink 0 +43: open unlink 0 +42: open unlink 0 +41: ok +40: ok +39: ok +38: ok +37: ok +36: ok +35: ok +34: open unlink 0 +33: ok +32: length 0 +31: open unlink 0 +30: open unlink 0 +29: open unlink 0 +28: open unlink 0 +27: open unlink 0 +26: open unlink 0 +25: open unlink 0 +24: open unlink 0 +23: open unlink 0 +22: open unlink 0 +21: open unlink 0 +20: open unlink 0 +19: open unlink 0 +18: open unlink 0 +17: open unlink 0 +16: open unlink 0 +15: open unlink 0 +14: open unlink 0 +13: open unlink 0 +12: open unlink 0 +11: open unlink 0 +10: open unlink 0 +9: open unlink 0 +8: open unlink 0 +7: open unlink 0 +6: open unlink 0 +5: open unlink 0 +4: open unlink 0 +3: open unlink 0 +2: open unlink 0 +1: open unlink 0 + + valid chars = 69:130 130:69 69:69 65:131 131:65 65:65 65:133 133:65 65:65 69:136 136:69 69:69 69:137 137:69 69:69 69:138 138:69 69:69 73:139 139:73 73:73 73:140 140:73 73:73 73:141 141:73 73:73 79:147 147:79 79:79 79:149 149:79 79:79 85:150 150:85 85:85 85:151 151:85 85:85 89:152 152:89 89:89 65:160 160:65 65:65 73:161 161:73 73:73 79:162 162:79 79:79 85:163 163:85 85:85 33 35 36 37 38 39 40 41 45 48 49 50 51 52 53 54 55 56 57 64 97:65 98:66 99:67 100:68 101:69 102:70 103:71 104:72 105:73 106:74 107:75 108:76 109:77 110:78 111:79 112:80 113:81 114:82 115:83 116:84 117:85 118:86 119:87 120:88 121:89 122:90 94 95 96 123 125 126 127 135:128 132:142 134:143 144 145:146 148:153 129:154 155 156 157 158 159 164:165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 diff --git a/examples/validchars/readme b/examples/validchars/readme new file mode 100644 index 00000000000..6487fbd766a --- /dev/null +++ b/examples/validchars/readme @@ -0,0 +1,101 @@ +Note: All files in this directory are DOS formatted (CRLF line terminator). + +!!! VIRUS WARNING !!! I do not know if VALIDCHR.COM is virus free !!! +I think that my system is virus free here because I do not run any games +or other copied software. I only run Shareware/Freeware etc. from CD-ROMs +or from registered disks, however I do not use viral scanners because +I have not registered any (I consider `having no sex' is better than +`testing for AIDS on a regular basis', if you know what I mean). + +This is VALIDCHR, a little DOS program I wrote to create +an apropriate `valid chars =' config parameter. +It is freeware and is thought to be distributed freely with Samba. + +WARNING: + Your SMB driver may use another character map as the one VALIDCHR + sees. The only way you can tell this is that some file names fail. + Under Win95 everything is fine, though. + +Usage: + c: + mkdir junk_dir + cd junk_dir + a:validchr > a:output.log + cd .. + rmdir junk_dir + +Siedeffects: + Files named *.TST may be deleted. + +Verification: + For diagnostic purpose you can run VALIDCHR on a Samba mounted drive. + Then you can use unix diff to compare the output of the network and + the hard drive. These two outputs usually differ! However there + should be few differences. I get following on Win95 (c: visa e:) + 104c104 + < 152: length 0 + --- + > 152: 95 + (diff line for `valid chars =' deleted because it's uninteresting) + You can see, `y diaresis' can be mapped on the network drive while + it cannot be mapped on the hard drive. Everything else is identical. + However this gives a hint that one can improve the mapping. + +Bugs: + Yes, probably some. + + +VALIDCHR must be run on the system which character mapping should be probed. +It must be run on the hard drive for this. VALIDCHR ALTERS THE CURRENT +DIRECTORY AND REMOVES SOME FILES, SO ALWAYS RUN IT IN A junk DIRECTORY !!! +You should redirect the output of VALIDCHR. At the end of the output is a +line like + valid chars = x:y y:x x:x ... a:b c ... +which is suitable for your smb.conf file. (you should remove the DOS CR +character, because DOS uses CRLF while Unix uses LF only.) + +Note that some mappings at the beginning of the `valid chars =' line like +A:B B:A B:B +might look a little bit strange to you, however sometimes character A +has to be mapped to character B independently of a default mapping +to uppercase or lowercase while character B must not be touched. I found +this out the hard way ... Consider it a crude workaround, because Samba +lacks the possibility to map characters in one direction only! + +VALIDCHR usually issues one warning for character 32. +You may ignore these and any other warnings. + +VALIDCHR does not test for character NUL (this is the directory end marker). + +validchr.c is the source code to validchr.com + You may do anything with the source code (copy, change, sell, burn) +validchr.com is a Borland C compiled binary. + Beware, it may contain a virus (if my system contains one). +nwdos70.out is the output of an VALIDCHR-run under Novell DOS 7.0 + while no codepage (no display.sys) was active. +msdos70.out is the output of an VALIDCHR-run under MS-DOS 7.0 (Win95 DOS) + while codepage 850 was active. + +I have no other MS-DOS systems at home currently. +(I have access to MS-DOS 3.0, 3.2, 3.3, 5.0 and 6.22, however I have no time + to run VALIDCHR there) + +Some words to the output +(for people not fammiliar with programming language C): + +probed_char: [text] mapped_char + +probed_char is the character probed to be written to disk +text may be empty or contain: + open File could not be opened. + close File could not be closed (should not happen) + length File name was shortened (usually occurs on SPC) + unlink File cannot be unlinked (usually when open fails) +mapped_char is the character which is used by MS-DOS in the directory + This is usually the uppercase character. + The mapped character is 0 if something failed (you may say + that the character is not supported) + +The last line in the output is documented in the smb.conf manual page ;) + +tino@augsburg.net diff --git a/examples/validchars/validchr.c b/examples/validchars/validchr.c new file mode 100644 index 00000000000..415546cb841 --- /dev/null +++ b/examples/validchars/validchr.c @@ -0,0 +1,123 @@ +/* by tino@augsburg.net + */ + +#include +#include + +#include + +unsigned char +test(void) +{ + DIR *dir; + struct dirent *dp; + unsigned char c; + + if ((dir=opendir("."))==0) + { + perror("open ."); + return 0; + } + c = 0; + while ((dp=readdir(dir))!=0) + { + size_t len; + + len = strlen(dp->d_name); + if (len<4) + continue; + if (strcmp(dp->d_name+len-4, ".TST")) + continue; + if (len!=5) + { + fprintf(stderr, "warning: %s\n", dp->d_name); + printf(" length"); + continue; + } + if (c) + printf(" double%d\n", c); + c = dp->d_name[0]; + } + if (closedir(dir)) + perror("close ."); + return c; +} + +int +main(void) +{ + char name[256]; + unsigned char map[256], upper[256], lower[256]; + int i, j, c; + FILE *fd; + + if (test()) + { + printf("There are *.TST files, please remove\n"); + return 0; + } + for (i=0; ++i<256; ) + { + lower[i] = i; + upper[i] = 0; + } + for (i=256; --i; ) + { + map[i] = i; + strcpy(name, "..TST"); + name[0] = i; + printf("%d:", i); + if ((fd=fopen(name, "w"))==0) + printf(" open"); + else + fclose(fd); + c = test(); + if (unlink(name)) + printf(" unlink"); + if (c==i) + printf(" ok"); + else + printf(" %d", c); + printf("\n"); + if (c!=i) + { + upper[c]++; + lower[c] = i; + } + map[i] = c; + } + + /* Uppercase characters are detected above on: + * The character is mapped to itself and there is a + * character which maps to it. + * Lowercase characters are the lowest character pointing to another one. + * Else it is a one way character. + * + * For this reason we have to process the list + * 1) for 'one way' characters + * 'one way' is something which is no upper and no lower character. + * This is an awful, crude and ugly hack due to missing Samba support. + * 2) for true uppercase/lowercase characters + * 3) for standalone characters + * Note that there might be characters which do not fall into 1 to 3. + */ + printf("\n valid chars ="); + for (i=0; ++i<256; ) + if (map[i] && map[i]!=i && lower[map[i]]!=i) + { + if (!upper[i]) + printf(" %d:%d %d:%d %d:%d", /*1*/ + map[i], i, i, map[i], map[i], map[i]); + else + fprintf(stderr, "ignoring map %d->%d because of %d->%d\n", + lower[i], i, i, map[i]); + } + for (i=0; ++i<256; ) + if (map[i] && map[i]==i) + if (upper[i]) + printf(" %d:%d", lower[i], i); /*2*/ + else + printf(" %d", i); /*3*/ + printf("\n"); + return 0; +} diff --git a/examples/validchars/validchr.com b/examples/validchars/validchr.com new file mode 100644 index 0000000000000000000000000000000000000000..ce159568369d9e8ccc6eacf8674ec2d8eb78ac69 GIT binary patch literal 9792 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