This is draft with some debug output to file and it requires hard refinement.
Code: Select all
*** utils.c-orig 2011-08-14 12:24:00.645183544 +0400
--- utils.c 2011-08-14 17:32:02.242301478 +0400
***************
*** 583,597 ****
--- 583,612 ----
return 0;
}
+ #define NAME_DEBUG
+ #ifdef NAME_DEBUG
+ FILE *name_log=NULL;
+ #endif
+
char*
tr_buildPath( const char *first_element, ... )
{
size_t bufLen = 0;
const char * element;
char * buf;
+ /* char * buf2;*/
char * pch;
va_list vl;
+ #ifdef NAME_DEBUG
+ size_t lastLen;
+ size_t namePos;
+ unsigned char checksum = 0;
+ if( name_log == NULL) {
+ name_log = fopen("/tmp/name_debug.log", "wb");
+ }
+ #endif
+
/* pass 1: allocate enough space for the string */
va_start( vl, first_element );
element = first_element;
***************
*** 600,605 ****
--- 615,625 ----
element = va_arg( vl, const char* );
}
pch = buf = tr_new( char, bufLen );
+
+ #ifdef NAME_DEBUG
+ /*buf2 = tr_new( char, bufLen );*/
+ #endif
+
va_end( vl );
/* pass 2: build the string piece by piece */
***************
*** 607,612 ****
--- 627,635 ----
element = first_element;
while( element ) {
const size_t elementLen = strlen( element );
+ #ifdef NAME_DEBUG
+ lastLen=elementLen;
+ #endif
memcpy( pch, element, elementLen );
pch += elementLen;
*pch++ = TR_PATH_DELIMITER;
***************
*** 621,626 ****
--- 644,690 ----
/* sanity checks & return */
assert( pch - buf == (off_t)bufLen );
+ #ifdef NAME_DEBUG
+ namePos=bufLen;
+ while( namePos && buf[namePos-1] != TR_PATH_DELIMITER ) {
+ namePos--;
+ }
+ fprintf(name_log, "name at %7d len %7d buf %7d %s\n", namePos, bufLen-namePos-1, bufLen, buf);
+ /* if length>255
+ ... find start of extension, let it be a string end
+ ... cut from file name by excess length
+ ... if first char after cut if 0b10xxxxxx (utf8 continuation) cut more until start of UTF-8 character
+ */
+ if( (bufLen-namePos-1) > 255 ) {
+ size_t excess=bufLen-namePos-1-255+2; /* 2 bytes for control sum */
+ size_t extPos;
+ size_t cutPos;
+ extPos=bufLen;
+ while( extPos>namePos && buf[extPos-1] != '.' ) { /* finish after dot or at string start */
+ extPos--;
+ }
+ if( extPos<(namePos+excess+4) ) { /* +4 - reserve for utf-8 truncating */
+ /* too long extension or dot was not found, reset to end of string */
+ extPos=bufLen;
+ }
+ extPos--; /* go to point to dot or to zero at string end */
+
+ cutPos = extPos -excess;
+ while( cutPos>namePos && ((buf[cutPos]&0xC0)==0x80) ) { /* remove UTF-8 continuations */
+ cutPos--;
+ }
+ /*strcpy( buf2, buf );*/
+ for( size_t counter = cutPos; counter<=extPos; counter++ ) {
+ checksum ^= buf[counter];
+ }
+ sprintf( buf+cutPos, "%02X", checksum );
+ strcpy( buf+cutPos+2, buf+extPos );
+ fprintf( name_log, "Cutted %d at %d ext %d result: %s\n", excess, cutPos, extPos, buf );
+ /* tr_free( buf2 );*/
+
+ };
+
+ #endif
return buf;
}