annotate sub/unrar_exec.c @ 36441:b75ebb89d803

Workaround VDPAU decode errors on aspect change on NVidia. The NVidia driver seems to expect a decoder reinit on aspect change, otherwise giving a nonsense VDP_STATUS_INVALID_SIZE error. Since decode and display can run out of sync, we do not in fact know when an aspect change will happen during decode but only when we want to display that decoded frame, and with threaded decoding these will differ significantly. So just catch the error and retry decoding instead, this also has the advantage of not affecting (and possibly costing performance) drivers without this issue.
author reimar
date Sun, 08 Dec 2013 15:07:00 +0000
parents 804c3926503b
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
32459
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
1 /*
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
2 * List files and extract file from rars by using external executable unrar.
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
3 *
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
4 * Copyright (C) 2005 Jindrich Makovicka <makovick gmail com>
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
5 * Copyright (C) 2007 Ulion <ulion2002 gmail com>
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
6 *
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
7 * This file is part of MPlayer.
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
8 *
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
9 * MPlayer is free software; you can redistribute it and/or modify
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
10 * it under the terms of the GNU General Public License as published by
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
11 * the Free Software Foundation; either version 2 of the License, or
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
12 * (at your option) any later version.
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
13 *
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
14 * MPlayer is distributed in the hope that it will be useful,
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
17 * GNU General Public License for more details.
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
18 *
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
19 * You should have received a copy of the GNU General Public License along
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
20 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
22 */
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
23
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
24 #include <sys/wait.h>
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
25 #include <unistd.h>
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
26 #include <fcntl.h>
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
27 #include <stdlib.h>
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
28 #include <stdio.h>
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
29 #include <string.h>
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
30 #include <errno.h>
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
31 #include <locale.h>
32464
22888a8cb312 Do not use a path for including files in the same directory.
reimar
parents: 32459
diff changeset
32 #include "unrar_exec.h"
32459
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
33
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
34 #include "mp_msg.h"
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
35
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
36 #define UNRAR_LIST 1
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
37 #define UNRAR_EXTRACT 2
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
38
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
39 char* unrar_executable = NULL;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
40
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
41 static FILE* launch_pipe(pid_t *apid, const char *executable, int action,
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
42 const char *archive, const char *filename)
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
43 {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
44 if (!executable || access(executable, R_OK | X_OK)) return NULL;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
45 if (access(archive, R_OK)) return NULL;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
46 {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
47 int mypipe[2];
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
48 pid_t pid;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
49
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
50 if (pipe(mypipe)) {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
51 mp_msg(MSGT_GLOBAL, MSGL_ERR, "UnRAR: Cannot create pipe.\n");
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
52 return NULL;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
53 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
54
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
55 pid = fork();
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
56 if (pid == 0) {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
57 /* This is the child process. Execute the unrar executable. */
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
58 close(mypipe[0]);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
59 // Close MPlayer's stdin, stdout and stderr so the unrar binary
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
60 // can not mess them up.
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
61 // TODO: Close all other files except the pipe.
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
62 close(0); close(1); close(2);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
63 // Assign new stdin, stdout and stderr and check they actually got the
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
64 // right descriptors.
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
65 if (open("/dev/null", O_RDONLY) != 0 || dup(mypipe[1]) != 1
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
66 || open("/dev/null", O_WRONLY) != 2)
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
67 _exit(EXIT_FAILURE);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
68 if (action == UNRAR_LIST)
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
69 execl(executable, executable, "v", archive, NULL);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
70 else if (action == UNRAR_EXTRACT)
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
71 execl(executable, executable, "p", "-inul", "-p-",
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
72 archive,filename,NULL);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
73 mp_msg(MSGT_GLOBAL, MSGL_ERR, "UnRAR: Cannot execute %s\n", executable);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
74 _exit(EXIT_FAILURE);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
75 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
76 if (pid < 0) {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
77 /* The fork failed. Report failure. */
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
78 mp_msg(MSGT_GLOBAL, MSGL_ERR, "UnRAR: Fork failed\n");
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
79 return NULL;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
80 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
81 /* This is the parent process. Prepare the pipe stream. */
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
82 close(mypipe[1]);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
83 *apid = pid;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
84 if (action == UNRAR_LIST)
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
85 mp_msg(MSGT_GLOBAL, MSGL_V,
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
86 "UnRAR: call unrar with command line: %s v %s\n",
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
87 executable, archive);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
88 else if (action == UNRAR_EXTRACT)
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
89 mp_msg(MSGT_GLOBAL, MSGL_V,
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
90 "UnRAR: call unrar with command line: %s p -inul -p- %s %s\n",
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
91 executable, archive, filename);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
92 return fdopen(mypipe[0], "r");
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
93 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
94 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
95
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
96 #define ALLOC_INCR 1 * 1024 * 1024
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
97 int unrar_exec_get(unsigned char **output, unsigned long *size,
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
98 const char *filename, const char *rarfile)
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
99 {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
100 int bufsize = ALLOC_INCR, bytesread;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
101 pid_t pid;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
102 int status = 0;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
103 FILE *rar_pipe;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
104
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
105 rar_pipe=launch_pipe(&pid,unrar_executable,UNRAR_EXTRACT,rarfile,filename);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
106 if (!rar_pipe) return 0;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
107
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
108 *size = 0;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
109
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
110 *output = malloc(bufsize);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
111
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
112 while (*output) {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
113 bytesread=fread(*output+*size, 1, bufsize-*size, rar_pipe);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
114 if (bytesread <= 0)
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
115 break;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
116 *size += bytesread;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
117 if (*size == bufsize) {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
118 char *p;
35883
804c3926503b Fix a potential integer overflow.
reimar
parents: 32464
diff changeset
119 if (bufsize >= 0x7fffffff - ALLOC_INCR)
804c3926503b Fix a potential integer overflow.
reimar
parents: 32464
diff changeset
120 break;
32459
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
121 bufsize += ALLOC_INCR;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
122 p = realloc(*output, bufsize);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
123 if (!p)
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
124 free(*output);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
125 *output = p;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
126 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
127 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
128 fclose(rar_pipe);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
129 pid = waitpid(pid, &status, 0);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
130 if (!*output || !*size || (pid == -1 && errno != ECHILD) ||
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
131 (pid > 0 && status)) {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
132 free(*output);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
133 *output = NULL;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
134 *size = 0;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
135 return 0;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
136 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
137 if (bufsize > *size) {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
138 char *p = realloc(*output, *size);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
139 if (p)
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
140 *output = p;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
141 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
142 mp_msg(MSGT_GLOBAL, MSGL_V, "UnRAR: got file %s len %lu\n", filename,*size);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
143 return 1;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
144 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
145
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
146 #define PARSE_NAME 0
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
147 #define PARSE_PROPS 1
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
148
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
149 int unrar_exec_list(const char *rarfile, ArchiveList_struct **list)
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
150 {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
151 char buf[1024], fname[1024];
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
152 char *p;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
153 pid_t pid;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
154 int status = 0, file_num = -1, ignore_next_line = 0, state = PARSE_NAME;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
155 FILE *rar_pipe;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
156 ArchiveList_struct *alist = NULL, *current = NULL, *new;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
157
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
158 rar_pipe = launch_pipe(&pid, unrar_executable, UNRAR_LIST, rarfile, NULL);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
159 if (!rar_pipe) return -1;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
160 while (fgets(buf, sizeof(buf), rar_pipe)) {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
161 int packsize, unpsize, ratio, day, month, year, hour, min;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
162 int llen = strlen(buf);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
163 // If read nothing, we got a file_num -1.
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
164 if (file_num == -1)
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
165 file_num = 0;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
166 if (buf[llen-1] != '\n')
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
167 // The line is too long, ignore it.
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
168 ignore_next_line = 2;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
169 if (ignore_next_line) {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
170 --ignore_next_line;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
171 state = PARSE_NAME;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
172 continue;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
173 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
174 // Trim the line.
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
175 while (llen > 0 && strchr(" \t\n\r\v\f", buf[llen-1]))
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
176 --llen;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
177 buf[llen] = '\0';
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
178 p = buf;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
179 while (*p && strchr(" \t\n\r\v\f", *p))
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
180 ++p;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
181 if (!*p) {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
182 state = PARSE_NAME;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
183 continue;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
184 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
185
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
186 if (state == PARSE_PROPS && sscanf(p, "%d %d %d%% %d-%d-%d %d:%d",
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
187 &unpsize, &packsize, &ratio, &day,
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
188 &month, &year, &hour, &min) == 8) {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
189 new = calloc(1, sizeof(ArchiveList_struct));
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
190 if (!new) {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
191 file_num = -1;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
192 break;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
193 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
194 if (!current)
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
195 alist = new;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
196 else
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
197 current->next = new;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
198 current = new;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
199 current->item.Name = strdup(fname);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
200 state = PARSE_NAME;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
201 if (!current->item.Name) {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
202 file_num = -1;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
203 break;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
204 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
205 current->item.PackSize = packsize;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
206 current->item.UnpSize = unpsize;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
207 ++file_num;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
208 continue;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
209 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
210 strcpy(fname, p);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
211 state = PARSE_PROPS;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
212 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
213 fclose(rar_pipe);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
214 pid = waitpid(pid, &status, 0);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
215 if (file_num < 0 || (pid == -1 && errno != ECHILD) ||
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
216 (pid > 0 && status)) {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
217 unrar_exec_freelist(alist);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
218 return -1;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
219 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
220 if (!alist)
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
221 return -1;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
222 *list = alist;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
223 mp_msg(MSGT_GLOBAL, MSGL_V, "UnRAR: list got %d files\n", file_num);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
224 return file_num;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
225 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
226
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
227 void unrar_exec_freelist(ArchiveList_struct *list)
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
228 {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
229 ArchiveList_struct* tmp;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
230
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
231 while (list) {
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
232 tmp = list->next;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
233 free(list->item.Name);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
234 free(list);
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
235 list = tmp;
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
236 }
1a605463f62b Move vobsub.[ch] and unrar_exec.[ch] to the sub directory.
cigaes
parents:
diff changeset
237 }