Archive-Chm
view release on metacpan or search on metacpan
if (ui->path[0] != '/')
return CHM_ENUMERATOR_CONTINUE;
if (snprintf((char*)buffer, sizeof(buffer), "%s%s", ctx->base_path, ui->path) > 1024)
return CHM_ENUMERATOR_FAILURE;
if (ui->length != 0)
{
FILE *fout;
LONGINT64 len, remain=ui->length;
LONGUINT64 offset = 0;
if (set_verbose("Archive::Chm", -1))
fprintf(_set_logfile(NULL), "--> %s\n", ui->path);
if ((fout = fopen((const char*)buffer, "wb")) == NULL)
{
/* make sure that it isn't just a missing directory before we abort */
unsigned char newbuf[32768];
strcpy((char*)newbuf, (const char*)buffer);
i = rindex((const char*)newbuf, '/');
*i = '\0';
_rmkdir((char*)newbuf);
if ((fout = fopen((const char*)buffer, "wb")) == NULL)
return CHM_ENUMERATOR_FAILURE;
}
while (remain != 0)
{
len = chm_retrieve_object(h, ui, buffer, offset, 32768);
if (len > 0)
{
fwrite(buffer, 1, (size_t)len, fout);
offset += len;
remain -= len;
}
else
{
fprintf(stderr, "incomplete file: %s\n", ui->path);
break;
}
}
fclose(fout);
}
else
{
if (_rmkdir((char*)buffer) == -1)
return CHM_ENUMERATOR_FAILURE;
}
return CHM_ENUMERATOR_CONTINUE;
}
/*-------------------------------------------------------------------------------
// Function that checks if the file/directory given as an argument exists.
//------------------------------------------------------------------------------*/
static int _dir_exists(const char *path)
{
struct stat statbuf;
if (stat(path, &statbuf) != -1)
return 1;
else
return 0;
}
/*-------------------------------------------------------------------------------
// Function to make a given directory for use when extracting to a path.
//------------------------------------------------------------------------------*/
static int _rmkdir(char *path)
{
//strip off trailing components unless we can stat the directory, or we
//have run out of components
char *i = rindex(path, '/');
if(path[0] == '\0' || _dir_exists(path))
return 0;
if (i != NULL)
{
*i = '\0';
_rmkdir(path);
*i = '/';
mkdir(path, 0777);
}
#ifdef WIN32
return 0;
#else
if (_dir_exists(path))
return 0;
else
return -1;
#endif
}
/*-------------------------------------------------------------------------------
// Function to set the error message associated with the Archive::Chm object.
//------------------------------------------------------------------------------*/
void _set_errmsg(SV* obj, char* msg)
{
ChmFile* chm = (ChmFile*)SvIV(SvRV(obj));
if (chm->errmsg)
free(chm->errmsg);
chm->errmsg = strdup(msg);
}
/*-------------------------------------------------------------------------------
// Get rid of faulty strndup implementations...
//------------------------------------------------------------------------------*/
static char * my_strndup(const char *src, size_t len)
{
char *ret = NULL;
ret = calloc(len + (size_t)1, sizeof(char));
if ( !ret )
croak("Out of memory\n");
( run in 1.248 second using v1.01-cache-2.11-cpan-98e64b0badf )