Coverage Report

Created: 2023-06-07 06:20

/src/mupdf/source/fitz/directory.c
Line
Count
Source (jump to first uncovered line)
1
// Copyright (C) 2004-2021 Artifex Software, Inc.
2
//
3
// This file is part of MuPDF.
4
//
5
// MuPDF is free software: you can redistribute it and/or modify it under the
6
// terms of the GNU Affero General Public License as published by the Free
7
// Software Foundation, either version 3 of the License, or (at your option)
8
// any later version.
9
//
10
// MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
11
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
// FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
13
// details.
14
//
15
// You should have received a copy of the GNU Affero General Public License
16
// along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
17
//
18
// Alternative licensing terms are available from the licensor.
19
// For commercial licensing, see <https://www.artifex.com/> or contact
20
// Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
21
// CA 94129, USA, for further information.
22
23
#include "mupdf/fitz.h"
24
25
#include <string.h>
26
#include <errno.h>
27
#include <sys/stat.h>
28
29
#ifdef _MSC_VER
30
#define stat _stat
31
#endif
32
33
typedef struct
34
{
35
  fz_archive super;
36
37
  char *path;
38
} fz_directory;
39
40
static void drop_directory(fz_context *ctx, fz_archive *arch)
41
0
{
42
0
  fz_directory *dir = (fz_directory *) arch;
43
44
0
  fz_free(ctx, dir->path);
45
0
}
46
47
static fz_stream *open_dir_entry(fz_context *ctx, fz_archive *arch, const char *name)
48
0
{
49
0
  fz_directory *dir = (fz_directory *) arch;
50
0
  char path[2048];
51
0
  fz_strlcpy(path, dir->path, sizeof path);
52
0
  fz_strlcat(path, "/", sizeof path);
53
0
  fz_strlcat(path, name, sizeof path);
54
0
  return fz_open_file(ctx, path);
55
0
}
56
57
static fz_buffer *read_dir_entry(fz_context *ctx, fz_archive *arch, const char *name)
58
0
{
59
0
  fz_directory *dir = (fz_directory *) arch;
60
0
  char path[2048];
61
0
  fz_strlcpy(path, dir->path, sizeof path);
62
0
  fz_strlcat(path, "/", sizeof path);
63
0
  fz_strlcat(path, name, sizeof path);
64
0
  return fz_read_file(ctx, path);
65
0
}
66
67
static int has_dir_entry(fz_context *ctx, fz_archive *arch, const char *name)
68
0
{
69
0
  fz_directory *dir = (fz_directory *) arch;
70
0
  char path[2048];
71
0
  fz_strlcpy(path, dir->path, sizeof path);
72
0
  fz_strlcat(path, "/", sizeof path);
73
0
  fz_strlcat(path, name, sizeof path);
74
0
  return fz_file_exists(ctx, path);
75
0
}
76
77
int
78
fz_is_directory(fz_context *ctx, const char *path)
79
0
{
80
0
  struct stat info;
81
82
0
  if (stat(path, &info) < 0)
83
0
    return 0;
84
85
0
  return S_ISDIR(info.st_mode);
86
0
}
87
88
fz_archive *
89
fz_open_directory(fz_context *ctx, const char *path)
90
0
{
91
0
  fz_directory *dir;
92
93
0
  if (!fz_is_directory(ctx, path))
94
0
    fz_throw(ctx, FZ_ERROR_GENERIC, "'%s' is not a directory", path);
95
96
0
  dir = fz_new_derived_archive(ctx, NULL, fz_directory);
97
0
  dir->super.format = "dir";
98
0
  dir->super.has_entry = has_dir_entry;
99
0
  dir->super.read_entry = read_dir_entry;
100
0
  dir->super.open_entry = open_dir_entry;
101
0
  dir->super.drop_archive = drop_directory;
102
103
0
  fz_try(ctx)
104
0
  {
105
0
    dir->path = fz_strdup(ctx, path);
106
0
  }
107
0
  fz_catch(ctx)
108
0
  {
109
0
    fz_drop_archive(ctx, &dir->super);
110
0
    fz_rethrow(ctx);
111
0
  }
112
113
0
  return &dir->super;
114
0
}