Add libmar to build update tools to the repo.
[working/Evergreen.git] / Open-ILS / xul / staff_client / external / libmar / src / mar_extract.c
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
3 /*
4  * This file is part of Evergreen.
5  *
6  * Evergreen is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published
8  * by the Free Software Foundation, either version 2 of the License,
9  * or (at your option) any later version.
10  *
11  * Evergreen is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Evergreen.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  * This Source Code Form is derived from code that was originally
20  * subject to the terms of the Mozilla Public License, v. 2.0 and
21  * included in Evergreen.  You may, therefore, use this Source Code
22  * Form under the terms of the Mozilla Public License 2.0.  This
23  * licensing option does not affect the larger Evergreen project, only
24  * the Source Code Forms bearing this exception are affected.  If a
25  * copy of the MPL was not distributed with this file, You can obtain
26  * one at http://mozilla.org/MPL/2.0/.
27  */
28
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <fcntl.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include "mar_private.h"
35 #include "mar.h"
36
37 #ifdef XP_WIN
38 #include <io.h>
39 #include <direct.h>
40 #endif
41
42 /* Ensure that the directory containing this file exists */
43 static int mar_ensure_parent_dir(const char *path)
44 {
45   char *slash = strrchr(path, '/');
46   if (slash)
47   {
48     *slash = '\0';
49     mar_ensure_parent_dir(path);
50 #ifdef XP_WIN
51     _mkdir(path);
52 #else
53     mkdir(path, 0755);
54 #endif
55     *slash = '/';
56   }
57   return 0;
58 }
59
60 static int mar_test_callback(MarFile *mar, const MarItem *item, void *unused) {
61   FILE *fp;
62   char buf[BLOCKSIZE];
63   int fd, len, offset = 0;
64
65   if (mar_ensure_parent_dir(item->name))
66     return -1;
67
68 #ifdef XP_WIN
69   fd = _open(item->name, _O_BINARY|_O_CREAT|_O_TRUNC|_O_WRONLY, item->flags);
70 #else
71   fd = creat(item->name, item->flags);
72 #endif
73   if (fd == -1)
74     return -1;
75
76   fp = fdopen(fd, "wb");
77   if (!fp)
78     return -1;
79
80   while ((len = mar_read(mar, item, offset, buf, sizeof(buf))) > 0) {
81     if (fwrite(buf, len, 1, fp) != 1)
82       break;
83     offset += len;
84   }
85
86   fclose(fp);
87   return len == 0 ? 0 : -1;
88 }
89
90 int mar_extract(const char *path) {
91   MarFile *mar;
92   int rv;
93
94   mar = mar_open(path);
95   if (!mar)
96     return -1;
97
98   rv = mar_enum_items(mar, mar_test_callback, NULL);
99
100   mar_close(mar);
101   return rv;
102 }