modules/libmar/src/mar_extract.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include <sys/types.h>
     8 #include <sys/stat.h>
     9 #include <fcntl.h>
    10 #include <string.h>
    11 #include <stdlib.h>
    12 #include "mar_private.h"
    13 #include "mar.h"
    15 #ifdef XP_WIN
    16 #include <io.h>
    17 #include <direct.h>
    18 #endif
    20 /* Ensure that the directory containing this file exists */
    21 static int mar_ensure_parent_dir(const char *path)
    22 {
    23   char *slash = strrchr(path, '/');
    24   if (slash)
    25   {
    26     *slash = '\0';
    27     mar_ensure_parent_dir(path);
    28 #ifdef XP_WIN
    29     _mkdir(path);
    30 #else
    31     mkdir(path, 0755);
    32 #endif
    33     *slash = '/';
    34   }
    35   return 0;
    36 }
    38 static int mar_test_callback(MarFile *mar, const MarItem *item, void *unused) {
    39   FILE *fp;
    40   char buf[BLOCKSIZE];
    41   int fd, len, offset = 0;
    43   if (mar_ensure_parent_dir(item->name))
    44     return -1;
    46 #ifdef XP_WIN
    47   fd = _open(item->name, _O_BINARY|_O_CREAT|_O_TRUNC|_O_WRONLY, item->flags);
    48 #else
    49   fd = creat(item->name, item->flags);
    50 #endif
    51   if (fd == -1) {
    52     fprintf(stderr, "ERROR: could not create file in mar_test_callback()\n");
    53     perror(item->name);
    54     return -1;
    55   }
    57   fp = fdopen(fd, "wb");
    58   if (!fp)
    59     return -1;
    61   while ((len = mar_read(mar, item, offset, buf, sizeof(buf))) > 0) {
    62     if (fwrite(buf, len, 1, fp) != 1)
    63       break;
    64     offset += len;
    65   }
    67   fclose(fp);
    68   return len == 0 ? 0 : -1;
    69 }
    71 int mar_extract(const char *path) {
    72   MarFile *mar;
    73   int rv;
    75   mar = mar_open(path);
    76   if (!mar)
    77     return -1;
    79   rv = mar_enum_items(mar, mar_test_callback, NULL);
    81   mar_close(mar);
    82   return rv;
    83 }

mercurial