Changeset 1073


Ignore:
Timestamp:
Apr 4, 2017, 1:20:59 PM (8 years ago)
Author:
dmik
Message:

rpm: Better handle unixroot and absolute path concat on OS/2.

This fixes ticket #118.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • rpm/trunk/rpmio/rpmfileutil.c

    r594 r1073  
    381381}
    382382
     383#ifdef __EMX__
     384#define AT_UNIXROOT "/@unixroot"
     385#define AT_UNIXROOT_LEN (sizeof(AT_UNIXROOT) - 1)
     386#endif
     387
    383388/* @todo "../sbin/./../bin/" not correct. */
     389/*
     390 * @todo In general, this function recognizes ':' as path separators but it e.g.
     391 * doesn't trim trailing slashes within ':'. Also, ':' clashes with drive letter
     392 * separators on platforms like OS/2.
     393 */
    384394char *rpmCleanPath(char * path)
    385395{
    386 #ifdef __EMX__
    387     #define AT_UNIXROOT "/@unixroot"
    388     const int AT_UNIXROOT_LEN = strlen(AT_UNIXROOT);
    389 #endif
    390396    const char *s;
    391     char *se, *t, *te;
     397    char *se, *t, *te, *tb;
    392398    int begin = 1;
    393399
     
    396402
    397403/*fprintf(stderr, "*** RCP %s ->\n", path); */
    398     s = t = te = path;
    399 
    400 #ifdef __EMX__
    401     // clean '//X:/...' or '/X:/...'
    402     if (s[3] == ':')
    403         s++;
    404     if (s[2] == ':')
    405         s++;
    406     // clean '/@unixroot///@unixroot/...'
    407     if (strncmp( s, AT_UNIXROOT "//" AT_UNIXROOT, AT_UNIXROOT_LEN*2) == 0)
    408        s += (AT_UNIXROOT_LEN+2);
    409     // clean '/@unixroot//@unixroot/...'
    410     if (strncmp( s, AT_UNIXROOT "/" AT_UNIXROOT, AT_UNIXROOT_LEN*2) == 0)
    411        s += (AT_UNIXROOT_LEN);
    412     // clean '/@unixroot/@unixroot/...'
    413     if (strncmp( s, AT_UNIXROOT AT_UNIXROOT, AT_UNIXROOT_LEN*2) == 0)
    414        s += (AT_UNIXROOT_LEN);
    415     // clean '/@unixroot/X:/...'
    416     if (strncmp( s, AT_UNIXROOT, AT_UNIXROOT_LEN) == 0
    417         && s[AT_UNIXROOT_LEN+2] == ':')
    418        s += (AT_UNIXROOT_LEN+1);
    419 #endif
     404    s = t = te = tb = path;
    420405
    421406    while (*s != '\0') {
     
    424409        case ':':                       /* handle url's */
    425410            if (s[1] == '/' && s[2] == '/') {
    426                 *t++ = *s++;
    427                 *t++ = *s++;
    428                 break;
     411                se = tb;
     412                while (risalpha(*se) && se < t)
     413                    se++;
     414                if (se == t) {
     415                    *t++ = *s++;
     416                    *t++ = *s++;
     417                    break;
     418                }
    429419            }
    430420            begin=1;
     421            /* Save the new beginning */
     422            tb = t + 1;
    431423            break;
    432424        case '/':
     
    440432            while (s[1] == '/')
    441433                s++;
     434#ifdef __EMX__
     435            /*
     436             * On OS/2 under kLIBC root is often "/@unixroot" and it may be
     437             * concatenated several times, drop duplicates.
     438             */
     439            if ((t-tb) == AT_UNIXROOT_LEN &&
     440                !strncmp(tb, AT_UNIXROOT, AT_UNIXROOT_LEN) && !strncmp(s, AT_UNIXROOT, AT_UNIXROOT_LEN) && (s[AT_UNIXROOT_LEN] == '/' || !s[AT_UNIXROOT_LEN])) {
     441                s += AT_UNIXROOT_LEN;
     442/*fprintf(stderr, "*** dropping repetitive \"%.*s\"\n", AT_UNIXROOT_LEN, AT_UNIXROOT); */
     443            }
     444#endif
    442445            while (t > path && t[-1] == '/')
    443446                t--;
     
    485488            }
    486489            break;
    487 #ifdef __EMX__
     490#ifdef __OS2__
    488491        case '\\':
    489             *t = '/';
    490             break;
     492            *t++ = '/';
     493            s++;
     494            continue;
    491495#endif
    492496        default:
     497#ifdef __OS2__
     498            /*
     499             * If we encounter an absolute path starting with a drive letter
     500             * (a result of concatenation of some root dir and this path), it
     501             * should supersede any leading path components to become valid.
     502             */
     503            if (tb != s && (begin || s[-1] == '/') && risalpha(*s) && s[1] == ':' && (s[2] == '/' || s[2] == '\\')) {
     504/*fprintf(stderr, "*** superseding \"%.*s\" with absolute path\n", (t-tb), tb); */
     505                memmove(tb, s, strlen(s) + 1);
     506                s = t = te = tb + 1;
     507            }
     508#endif
    493509            begin = 0;
    494510            break;
Note: See TracChangeset for help on using the changeset viewer.