decode_URI(base);
stream_t *s = stream_UrlNew(access, base);
- if (!s)
+ if (!s || RarProbe(s))
goto error;
- int count = 0;
- rar_file_t **files;
- if ( RarProbe(s) || (
- RarParse(s, &count, &files, false ) &&
- RarParse(s, &count, &files, true )
- ) ||
- count <= 0 )
- goto error;
+
+ struct
+ {
+ int filescount;
+ rar_file_t **files;
+ unsigned int i_nbvols;
+ } newscheme = { 0, NULL, 0 }, oldscheme = { 0, NULL, 0 }, *p_scheme;
+
+ if (RarParse(s, &newscheme.filescount, &newscheme.files, &newscheme.i_nbvols, false)
+ || newscheme.filescount < 1 || newscheme.i_nbvols < 2 )
+ {
+ /* We might want to lookup old naming scheme, could be a part1.rar,part1.r00 */
+ stream_Seek(s, 0);
+ RarParse(s, &oldscheme.filescount, &oldscheme.files, &oldscheme.i_nbvols, true);
+ }
+
+ if (oldscheme.filescount >= newscheme.filescount && oldscheme.i_nbvols > newscheme.i_nbvols)
+ {
+ free(newscheme.files);
+ p_scheme = &oldscheme;
+ msg_Dbg(s, "using rar old naming for %d files nbvols %u", p_scheme->filescount, oldscheme.i_nbvols);
+ }
+ else if (newscheme.filescount)
+ {
+ free(oldscheme.files);
+ p_scheme = &newscheme;
+ msg_Dbg(s, "using rar new naming for %d files nbvols %u", p_scheme->filescount, oldscheme.i_nbvols);
+ }
+ else
+ {
+ msg_Info(s, "Invalid or unsupported RAR archive");
+ free(oldscheme.files);
+ free(newscheme.files);
+ goto error;
+ }
+
rar_file_t *file = NULL;
- for (int i = 0; i < count; i++) {
- if (!file && !strcmp(files[i]->name, name))
- file = files[i];
+ for (int i = 0; i < p_scheme->filescount; i++) {
+ if (!file && !strcmp(p_scheme->files[i]->name, name))
+ file = p_scheme->files[i];
else
- RarFileDelete(files[i]);
+ RarFileDelete(p_scheme->files[i]);
}
- free(files);
+ free(p_scheme->files);
if (!file)
goto error;
static const rar_pattern_t *FindVolumePattern(const char *location, bool b_extonly )
{
static const rar_pattern_t patterns[] = {
- { ".part01.rar", "%s.part%.2d.rar", 2, 99, false }, // new naming
+ { ".part1.rar", "%s.part%.1d.rar", 2, 9, false }, // new naming
+ { ".part01.rar", "%s.part%.2d.rar", 2, 99, false }, // new
{ ".part001.rar", "%s.part%.3d.rar", 2, 999, false }, // new
{ ".rar", "%s.%c%.2d", 0, 999, true }, // old
{ NULL, NULL, 0, 0, false },
return NULL;
}
-int RarParse(stream_t *s, int *count, rar_file_t ***file, bool b_extonly)
+int RarParse(stream_t *s, int *count, rar_file_t ***file, unsigned int *pi_nbvols,
+ bool b_extonly)
{
*count = 0;
*file = NULL;
+ *pi_nbvols = 1;
const rar_pattern_t *pattern = FindVolumePattern(s->psz_path, b_extonly);
int volume_offset = 0;
free(volume_mrl);
return VLC_SUCCESS;
}
+ (*pi_nbvols)++;
}
}
int RarProbe(stream_t *);
void RarFileDelete(rar_file_t *);
-int RarParse(stream_t *, int *, rar_file_t ***, bool);
+int RarParse(stream_t *, int *, rar_file_t ***, unsigned int *, bool);
int RarAccessOpen(vlc_object_t *);
void RarAccessClose(vlc_object_t *);
if (RarProbe(s->p_source))
return VLC_EGENERIC;
- int count;
- rar_file_t **files;
+ struct
+ {
+ int filescount;
+ rar_file_t **files;
+ unsigned int i_nbvols;
+ } newscheme = { 0, NULL, 0 }, oldscheme = { 0, NULL, 0 }, *p_scheme;
+
const int64_t position = stream_Tell(s->p_source);
- if ((RarParse(s->p_source, &count, &files, false) &&
- RarParse(s->p_source, &count, &files, true )) || count == 0 )
+
+ if (RarParse(s->p_source, &newscheme.filescount, &newscheme.files, &newscheme.i_nbvols, false)
+ || (newscheme.filescount < 2 && newscheme.i_nbvols < 2) )
+ {
+ /* We might want to lookup old naming scheme, could be a part1.rar,part1.r00 */
+ stream_Seek(s->p_source, 0);
+ RarParse(s->p_source, &oldscheme.filescount, &oldscheme.files, &oldscheme.i_nbvols, true );
+ }
+
+ if (oldscheme.filescount >= newscheme.filescount && oldscheme.i_nbvols > newscheme.i_nbvols)
+ {
+ free(newscheme.files);
+ p_scheme = &oldscheme;
+ }
+ else if (newscheme.filescount)
+ {
+ free(oldscheme.files);
+ p_scheme = &newscheme;
+ }
+ else
{
stream_Seek(s->p_source, position);
msg_Info(s, "Invalid or unsupported RAR archive");
- free(files);
+ free(oldscheme.files);
+ free(newscheme.files);
return VLC_EGENERIC;
}
free(encoded);
char *data = strdup("#EXTM3U\n");
- for (int i = 0; i < count; i++) {
- rar_file_t *f = files[i];
+ for (int i = 0; i < p_scheme->filescount; i++) {
+ rar_file_t *f = p_scheme->files[i];
char *next;
if (base && data &&
asprintf(&next, "%s"
RarFileDelete(f);
}
free(base);
- free(files);
+ free(p_scheme->files);
if (!data)
return VLC_EGENERIC;
stream_t *payload = stream_MemoryNew(s, (uint8_t*)data, strlen(data), false);