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 )