summaryrefslogtreecommitdiff
path: root/unrar/unrar.c
diff options
context:
space:
mode:
Diffstat (limited to 'unrar/unrar.c')
-rw-r--r--unrar/unrar.c46
1 files changed, 37 insertions, 9 deletions
diff --git a/unrar/unrar.c b/unrar/unrar.c
index b35f37e..1fc2882 100644
--- a/unrar/unrar.c
+++ b/unrar/unrar.c
@@ -364,7 +364,7 @@ TVFSResult VFSOpen(struct TVFSGlobs *globs, char *sName)
int PASCAL res = 0;
while ((res = RARReadHeaderEx(handle, header)) == 0)
{
- printf(" header->FileName = '%s', Flags = 0x%x\n", header->FileName, header->Flags);
+// printf(" header->FileName = '%s', Flags = 0x%x\n", header->FileName, header->Flags);
// Create a TVFSItem entry and fill all info
struct TVFSItem *item = (struct TVFSItem*)malloc(sizeof(struct TVFSItem));
@@ -397,9 +397,20 @@ TVFSResult VFSOpen(struct TVFSGlobs *globs, char *sName)
item->c_time = item->m_time;
item->a_time = item->m_time;
+// g_print (" valid = %d\n", g_utf8_validate (header->FileName, -1, NULL));
+
+ char *s;
+ if (g_utf8_validate (header->FileName, -1, NULL))
+ s = g_strdup (header->FileName);
+ else
+ s = wide_to_utf8 (header->FileNameW);
+// g_print (" ansi = '%s'\n wide = '%ls'\n utf8 = '%s'\n", header->FileName, header->FileNameW, s);
+
// Add item to the global list and continue with next file
- filelist_tree_add_item(globs->files, header->FileName, item, 0);
- int PASCAL res2 = RARProcessFile(handle, RAR_SKIP, NULL, NULL);
+ filelist_tree_add_item(globs->files, s, header->FileName, item, 0);
+ g_free (s);
+
+ int PASCAL res2 = RARProcessFile(handle, RAR_SKIP, NULL, NULL);
if (res2) printf("RARProcessFile result = %d\n", res2);
}
// printf("\nRARReadHeader result = %d\n", res);
@@ -657,11 +668,20 @@ TVFSResult VFSCopyOut(struct TVFSGlobs *globs, const char *sSrcName, const char
printf("(II) VFSCopyOut: copying file '%s' out to '%s'\n", sSrcName, sDstName);
+ struct PathTree *node = filelist_tree_find_node_by_path(globs->files, sSrcName);
+ if (! node) {
+ fprintf(stderr, "(EE) VFSCopyOut: cannot find file '%s'\n", sSrcName);
+ return cVFS_ReadErr;
+ }
+
TVFSResult Result = cVFS_OK;
+ gboolean found = FALSE;
- char *src;
- if (! IS_DIR_SEP(*sSrcName)) src = g_build_path("/", globs->curr_dir, sSrcName, NULL);
- else src = g_strdup(sSrcName);
+ char *src = node->original_pathstr;
+ if (! src) {
+ fprintf(stderr, "(WW) VFSCopyOut: cannot determine original filename\n");
+ src = (char *)sSrcName;
+ }
printf("(II) VFSCopyOut: new src path: '%s'\n", src);
@@ -713,6 +733,7 @@ TVFSResult VFSCopyOut(struct TVFSGlobs *globs, const char *sSrcName, const char
globs->extract_done = 0;
globs->extract_file_size = (int64_t)((int64_t)(header->UnpSizeHigh * 0x100000000) + (int64_t)header->UnpSize);
globs->extract_cancelled = FALSE;
+ found = TRUE;
int res2 = RARProcessFile(handle, RAR_EXTRACT, NULL, (char *)sDstName);
@@ -761,7 +782,10 @@ TVFSResult VFSCopyOut(struct TVFSGlobs *globs, const char *sSrcName, const char
break;
case ERAR_MISSING_PASSWORD:
Result = cVFS_BadPassword;
- if (globs->password) g_free (globs->password);
+ if (globs->password) {
+ g_free (globs->password);
+ globs->password = NULL;
+ }
break;
case ERAR_UNKNOWN:
default:
@@ -784,7 +808,11 @@ TVFSResult VFSCopyOut(struct TVFSGlobs *globs, const char *sSrcName, const char
}
free(archive_data);
- g_free(src);
+
+ if ((! found) && Result == cVFS_OK) {
+ fprintf(stderr, "(EE) VFSCopyOut: file not found in archive.\n");
+ Result = cVFS_ReadErr;
+ }
fprintf(stderr, "(II) VFSCopyOut: finished. \n");
return Result;
@@ -804,7 +832,7 @@ TVFSResult VFSCopyIn(struct TVFSGlobs *globs, const char *sSrcName, const char *
*
* - UTF-8, FName/FDisplayName and absolute/relative paths revision needed!
* - find a reliable way to catch bad password errors and free the cached invalid password
- * - no error reporting when archive is corrupted
+ * - no error reporting when archive is corrupted -- hopefully fixed by ask_question callback
* - archive testing (needs new VFS API)
*
***/