diff -uNr netatalk-1.6.0.org/etc/afpd/afp_options.c netatalk-1.6.0/etc/afpd/afp_options.c --- netatalk-1.6.0.org/etc/afpd/afp_options.c Sat Aug 24 14:00:07 2002 +++ netatalk-1.6.0/etc/afpd/afp_options.c Thu Dec 19 11:17:54 2002 @@ -61,8 +61,9 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif /* MIN */ -#define OPTIONS "dn:f:s:uc:g:P:ptDS:TL:F:U:Ivm:" +#define OPTIONS "dn:f:k:s:uc:g:P:ptDS:TL:F:U:Ivm:" #define LENGTH 512 +void select_charset(char *name); /* return an option. this uses an internal array, so it's necessary * to duplicate it if you want to hold it for long. this is probably @@ -435,6 +436,9 @@ while (( c = getopt( ac, av, OPTIONS )) != EOF ) { switch ( c ) { + case 'k' : + select_charset( optarg ); + break; case 'd' : options->flags |= OPTION_DEBUG; break; diff -uNr netatalk-1.6.0.org/etc/afpd/desktop.c netatalk-1.6.0/etc/afpd/desktop.c --- netatalk-1.6.0.org/etc/afpd/desktop.c Tue Nov 26 11:57:58 2002 +++ netatalk-1.6.0/etc/afpd/desktop.c Thu Dec 19 12:32:30 2002 @@ -604,10 +604,10 @@ return( path ); } -char *mtoupath(const struct vol *vol, char *mpath) +static char mtou_buf[MAXPATHLEN + 1], utom_buf[MAXPATHLEN + 1]; +char *mtoupathcap(const struct vol *vol, char *mpath) { - static char upath[ MAXPATHLEN + 1]; - char *m, *u; + char *m, *u, *maxu; int i = 0; if ( *mpath == '\0' ) { @@ -619,8 +619,9 @@ #endif /* FILE_MANGLING */ m = mpath; - u = upath; - while ( *m != '\0' ) { + u = mtou_buf; + maxu = u + sizeof( mtou_buf ) - 4; + while ( *m != '\0' && u < maxu ) { /* handle case conversion first */ if (vol->v_casefold & AFPVOL_MTOUUPPER) *m = diatoupper( *m ); @@ -673,21 +674,20 @@ LOG(log_debug, logtype_afpd, "mtoupath: '%s':'%s'", mpath, upath); #endif /* DEBUG */ - return( upath ); + return( mtou_buf ); } #define hextoint( c ) ( isdigit( c ) ? c - '0' : c + 10 - 'a' ) #define islxdigit(x) (!isupper(x)&&isxdigit(x)) -char *utompath(const struct vol *vol, char *upath) +char *utompathcap(const struct vol *vol, char *upath) { - static char mpath[ MAXPATHLEN + 1]; char *m, *u; int h; /* do the hex conversion */ u = upath; - m = mpath; + m = utom_buf; while ( *u != '\0' ) { /* we have a code page */ #if 1 @@ -725,7 +725,278 @@ LOG(log_debug, logtype_afpd, "utompath: '%s':'%s'", upath, mpath); #endif /* DEBUG */ - return( mpath ); + return( utom_buf ); +} + +static void euc2sjis( int *p1, int *p2) /* agrees w/ Samba on valid codes */ +{ + int row_offset, cell_offset; + unsigned char c1, c2; + + /* first convert EUC to ISO-2022 */ + c1 = *p1 & 0x7F; + c2 = *p2 & 0x7F; + + /* now convert ISO-2022 to Shift-JIS */ + row_offset = c1 < 95 ? 112 : 176; + cell_offset = c1 % 2 ? (c2 > 95 ? 32 : 31) : 126; + + *p1 = ((c1 + 1) >> 1) + row_offset; + *p2 = c2 + cell_offset; +} + +static void sjis2euc( int *p1, int *p2) /* agrees w/ Samba on valid codes */ +{ + int row_offset, cell_offset, adjust; + unsigned char c1, c2; + + c1 = *p1; + c2 = *p2; + + /* first convert Shift-JIS to ISO-2022 */ + adjust = c2 < 159; + row_offset = c1 < 160 ? 112 : 176; + cell_offset = adjust ? (c2 > 127 ? 32 : 31) : 126; + + c1 = ((c1 - row_offset) << 1) - adjust; + c2 -= cell_offset; + + /* now convert ISO-2022 to EUC */ + *p1 = c1 | 0x80; + *p2 = c2 | 0x80; +} + +static char *mtoupatheuc(const struct vol *vol, char *from) +{ + unsigned char *in, *out, *maxout; + int p, p2, fold, i = 0; + enum { UPPER = 1, LOWER }; + + if( vol->v_casefold & AFPVOL_MTOUUPPER) + fold = UPPER; + else if( vol->v_casefold & AFPVOL_MTOULOWER) + fold = LOWER; + else + fold = 0; + + in = (unsigned char *) from; + out = (unsigned char *) mtou_buf; + + if( *in ) { + maxout = out + sizeof( mtou_buf) - 4; + + while( out < maxout ) { + p = *in++; + + if( ((0x81 <= p) && (p <= 0x9F)) + || ((0xE0 <= p) && (p <= 0xEF)) ) { + /* JIS X 0208 */ + p2 = *in++; + if( ((0x40 <= p2) && (p2 <= 0x7E)) + || ((0x80 <= p2) && (p2 <= 0xFC)) ) + sjis2euc( &p, &p2); + *out++ = p; + p = p2; + + } else if( (0xA1 <= p) && (p <= 0xDF) ) { + *out++ = 0x8E; /* halfwidth katakana */ + } else if( p < 0x80) { + if( fold == UPPER) + p = diatoupper( p); + else if( fold == LOWER) + p = diatolower( p); + } + if( ( p == '/') || + ( i == 0 && p == '.' && (vol->v_flags & AFPVOL_USEDOTS) == 0) ) { + *out++ = ':'; + *out++ = hexdig[ ( p & 0xf0 ) >> 4 ]; + p = hexdig[ p & 0x0f ]; + } + i++; + *out++ = p; + if( p ) + continue; + break; + } + } else { + *out++ = '.'; + *out = 0; + } + + return mtou_buf; +} + +static char *utompatheuc( const struct vol *vol, char *from) +{ + unsigned char *in, *out, *maxout; + int p, p2, fold; + enum { UPPER = 1, LOWER }; + + if( vol->v_casefold & AFPVOL_UTOMUPPER) + fold = UPPER; + else if( vol->v_casefold & AFPVOL_UTOMLOWER) + fold = LOWER; + else + fold = 0; + + in = (unsigned char *) from; + out = (unsigned char *) utom_buf; + maxout = out + sizeof( utom_buf) - 3; + + while( out < maxout ) { + p = *in++; + + if( (0xA1 <= p) && (p <= 0xFE) ) { /* JIS X 0208 */ + p2 = *in++; + if( (0xA1 <= p2) && (p2 <= 0xFE) ) + euc2sjis( &p, &p2); + *out++ = p; + p = p2; + } else if( p == 0x8E ) { /* halfwidth katakana */ + p = *in++; + } else if( p < 0x80 ) { + if( fold == UPPER) + p = diatoupper( p); + else if( fold == LOWER) + p = diatolower( p); + } + if ( p == ':' && *(in) != '\0' && islxdigit( *(in)) && + *(in+1) != '\0' && islxdigit( *(in+1))) { + p = hextoint( *in ) << 4; + in++; + p |= hextoint( *in ); + in++; + } + *out++ = p; + if( p ) + continue; + break; + } + + return utom_buf; +} + +static char *mtoupathsjis(const struct vol *vol, char *from) +{ + unsigned char *in, *out, *maxout; + int p, p2, fold, i = 0; + enum { UPPER = 1, LOWER }; + + if( vol->v_casefold & AFPVOL_MTOUUPPER) + fold = UPPER; + else if( vol->v_casefold & AFPVOL_MTOULOWER) + fold = LOWER; + else + fold = 0; + + in = (unsigned char *) from; + out = (unsigned char *) mtou_buf; + if( *in ) { + maxout = out + sizeof( mtou_buf) - 3; + + while( out < maxout ) { + p = *in++; + + if( ((0x81 <= p) && (p <= 0x9F)) + || ((0xE0 <= p) && (p <= 0xEF)) ) { + /* JIS X 0208 */ + p2 = *in++; + *out++ = p; + p = p2; + + } else if( (0xA1 <= p) && (p <= 0xDF) ) { + ; /* halfwidth katakana */ + } else if( p < 0x80) { + if( fold == UPPER) + p = diatoupper( p); + else if( fold == LOWER) + p = diatolower( p); + } + if( ( p == '/') || + ( i == 0 && p == '.' && (vol->v_flags & AFPVOL_USEDOTS) == 0) ) { + *out++ = ':'; + *out++ = hexdig[ ( p & 0xf0 ) >> 4 ]; + p = hexdig[ p & 0x0f ]; + } + i++; + *out++ = p; + if( p ) + continue; + break; + } + } else { + *out++ = '.'; + *out = 0; + } + + return mtou_buf; +} + +static char *utompathsjis( const struct vol *vol, char *from) +{ + unsigned char *in, *out, *maxout; + int p, p2, fold; + enum { UPPER = 1, LOWER }; + + if( vol->v_casefold & AFPVOL_UTOMUPPER) + fold = UPPER; + else if( vol->v_casefold & AFPVOL_UTOMLOWER) + fold = LOWER; + else + fold = 0; + + in = (unsigned char *) from; + out = (unsigned char *) utom_buf; + maxout = out + sizeof( utom_buf) - 3; + + while( out < maxout ) { + p = *in++; + + if( (0xA1 <= p) && (p <= 0xFE) ) { /* JIS X 0208 */ + p2 = *in++; + *out++ = p; + p = p2; + } else if( p == 0x8E ) { /* do nothing */ + ; + } else if( p < 0x80 ) { + if( fold == UPPER) + p = diatoupper( p); + else if( fold == LOWER) + p = diatolower( p); + } + if ( p == ':' && *(in) != '\0' && islxdigit( *(in)) && + *(in+1) != '\0' && islxdigit( *(in+1))) { + p = hextoint( *in ) << 4; + in++; + p |= hextoint( *in ); + in++; + } + *out++ = p; + if( p ) + continue; + break; + } + + return utom_buf; +} + +char * (*_mtoupath) (const struct vol *vol, char *mpath) = mtoupathcap; +char * (*_utompath) (const struct vol *vol, char *upath) = utompathcap; + +/* choose translators for optional character set */ +void select_charset( char * name) +{ + + if( strcmp( name, "euc") == 0 ) { + _mtoupath = mtoupatheuc; + _utompath = utompatheuc; + } else if( strcmp( name, "sjis") == 0 ) { + _mtoupath = mtoupathsjis; + _utompath = utompathsjis; + } else { + _mtoupath = mtoupathcap; + _utompath = utompathcap; + } } int afp_addcomment(obj, ibuf, ibuflen, rbuf, rbuflen ) diff -uNr netatalk-1.6.0.org/etc/afpd/desktop.h netatalk-1.6.0/etc/afpd/desktop.h --- netatalk-1.6.0.org/etc/afpd/desktop.h Thu Jun 21 03:33:04 2001 +++ netatalk-1.6.0/etc/afpd/desktop.h Thu Dec 19 11:20:50 2002 @@ -46,8 +46,10 @@ typedef unsigned char CreatorType[4]; extern char *dtfile __P((const struct vol *, u_char [], char *)); -extern char *mtoupath __P((const struct vol *, char *)); -extern char *utompath __P((const struct vol *, char *)); +extern char *(*_mtoupath) __P((const struct vol *, char *)); +extern char *(*_utompath) __P((const struct vol *, char *)); +#define mtoupath(v,s) (*_mtoupath)((v), (s)) +#define utompath(v,s) (*_utompath)((v), (s)) extern u_char ucreator[]; #define validupath(vol, name) ((((vol)->v_flags & AFPVOL_USEDOTS) ? \