PAR-Packer

 view release on metacpan or  search on metacpan

myldr/mktmpdir.c  view on Meta::CPAN

#define CHUNK_SIZE (64 * 1024)
    char buf[CHUNK_SIZE + magic_size];
    off_t pos;
    int len;
    char *p;
    off_t file_size = lseek(fd, 0, 2);

    for (pos = (file_size-1) - (file_size-1) % CHUNK_SIZE;
         pos >= 0;
         pos -= CHUNK_SIZE) {
        CHECK(lseek(fd, pos, 0) != -1, "lseek failed");
        len = read(fd, buf, CHUNK_SIZE + magic_size);
        CHECK(len != -1, "read failed");
        p = par_memrmem(buf, len, PAR_MAGIC, magic_size);
        if (p)
            return pos + (p - buf);
    }
    return -1;
#undef CHUNK_SIZE
}

char *par_mktmpdir ( char **argv ) {
    int i;
    const char *tmpdir = NULL;
    const char *key = NULL , *val = NULL;

    /* NOTE: all arrays below are NULL terminated */
    const char *temp_dirs[] = {
        P_tmpdir,
#ifdef WIN32
        "C:\\TEMP",
#endif
        ".", NULL };
    const char *temp_keys[] = { "PAR_TMPDIR", "TMPDIR", "TEMPDIR",
                                 "TEMP", "TMP", NULL };
    const char *user_keys[] = { "USER", "USERNAME", NULL };

    const char *subdirbuf_prefix = "par-";
    const char *subdirbuf_suffix = "";

    char *progname = NULL, *username = NULL;
    char *stmpdir = NULL, *top_tmpdir = NULL;
    int f, stmp_len = 0;
    char sha1[cache_name_size + 1];

    if ( (val = par_getenv("PAR_TEMP")) && strlen(val) ) {
        par_setup_libpath(val);
        return strdup(val);
    }

#ifdef WIN32
    {
        DWORD buflen = MAXPATHLEN;
        username = malloc(MAXPATHLEN);
        GetUserName((LPTSTR)username, &buflen);
        // FIXME this is uncondifionally overwritten below - WTF?
    }
#endif

    /* Determine username */
    username = get_username_from_getpwuid();
    if ( !username ) { /* fall back to env vars */
        for ( i = 0 ; username == NULL && (key = user_keys[i]); i++) {
            if ( (val = par_getenv(key)) && strlen(val) )
                username = strdup(val);
        }
    }
    if ( username == NULL )
        username = "SYSTEM";

    /* sanitize username: encode all bytes as 2 hex digits */
    {
        char *hexname = malloc(2 * strlen(username) + 1);
        char *u, *h;
        for ( u = username, h = hexname ; *u != '\0' ; u++, h += 2)
            sprintf(h, "%02x", *(unsigned char*)u);
        username = hexname;
    }

    /* Try temp environment variables */
    for ( i = 0 ; tmpdir == NULL && (key = temp_keys[i]); i++ ) {
        if ( (val = par_getenv(key)) && strlen(val) && isWritableDir(val) ) {
            tmpdir = strdup(val);
            break;
        }
    }

#ifdef WIN32
    /* Try the windows temp directory */
    if ( tmpdir == NULL && (val = par_getenv("WinDir")) && strlen(val) ) {
        char* p = malloc(strlen(val) + 5 + 1);
        sprintf(p, "%s\\temp", val);
        if (isWritableDir(p)) {
            tmpdir = p;
        } else {
            free(p);
        }
    }
#endif

    /* Try default locations */
    for ( i = 0 ; tmpdir == NULL && (val = temp_dirs[i]) && strlen(val) ; i++ ) {
        if ( isWritableDir(val) ) {
            tmpdir = strdup(val);
        }
    }

    /* "$TEMP/par-$USER" */
    stmp_len =
        strlen(tmpdir) +
        strlen(subdirbuf_prefix) +
        strlen(username) +
        strlen(subdirbuf_suffix) + 1024;

    /* stmpdir is what we are going to return;
       top_tmpdir is the top $TEMP/par-$USER, needed to build stmpdir.
       NOTE: We need 2 buffers because snprintf() can't write to a buffer
       it is also reading from. */
    top_tmpdir = malloc( stmp_len );
    sprintf(top_tmpdir, "%s%s%s%s", tmpdir, dir_sep, subdirbuf_prefix, username);
#ifdef WIN32



( run in 1.725 second using v1.01-cache-2.11-cpan-0d23b851a93 )