Rizin
unix-like reverse engineering framework and cli tools
project.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2020-2021 Florian Märkl <info@florianmaerkl.de>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_project.h>
5 
6 #define RZ_PROJECT_KEY_TYPE "type"
7 #define RZ_PROJECT_KEY_VERSION "version"
8 
9 #define RZ_PROJECT_TYPE "rizin rz-db project"
10 
12  switch (err) {
14  return "success";
16  return "file access error";
18  return "invalid file type";
20  return "invalid project version";
22  return "newer project version";
24  return "invalid content encountered";
26  return "migration failed";
28  return "project file compression failed";
30  break;
31  }
32  return "unknown error";
33 }
34 
38  rz_serialize_core_save(sdb_ns(prj, "core", true), core, file);
40 }
41 
43  char *tmp_file = NULL;
44 
45  if (compress) {
46  int mkstemp_fd = rz_file_mkstemp("svprj", &tmp_file);
47  if (mkstemp_fd == -1 || !tmp_file) {
48  return RZ_PROJECT_ERR_FILE;
49  }
50  close(mkstemp_fd);
51  }
52 
54  const char *save_file = compress ? tmp_file : file;
55  RzProject *prj = sdb_new0();
56  if (!prj) {
58  goto tmp_file_err;
59  }
60  err = rz_project_save(core, prj, file);
61  if (err != RZ_PROJECT_ERR_SUCCESS) {
62  sdb_free(prj);
63  return err;
64  }
65  if (!sdb_text_save(prj, save_file, true)) {
67  }
68  sdb_free(prj);
69 
70  if (err != RZ_PROJECT_ERR_SUCCESS) {
71  goto tmp_file_err;
72  }
73 
74  if (compress && !rz_file_deflate(tmp_file, file)) {
76  goto tmp_file_err;
77  }
78 
79  rz_config_set(core->config, "prj.file", file);
80 
81 tmp_file_err:
82  rz_file_rm(tmp_file);
83  free(tmp_file);
84  return err;
85 }
86 
89  RzProject *prj = sdb_new0();
90  if (!prj) {
91  return NULL;
92  }
93 
94  char *tmp_file;
95  int mkstemp_fd = rz_file_mkstemp("ldprj", &tmp_file);
96  close(mkstemp_fd);
97 
98  if (mkstemp_fd == -1 || !tmp_file) {
99  free(tmp_file);
100  return NULL;
101  }
102 
103  const char *load_file = tmp_file;
104 
105  if (!rz_file_exists(file)) {
106  prj = NULL;
107  goto return_goto;
108  }
109  if (rz_file_is_deflated(file)) {
110  if (!rz_file_inflate(file, tmp_file)) {
111  prj = NULL;
112  goto return_goto;
113  }
114  } else {
115  load_file = file;
116  }
117 
118  if (!sdb_text_load(prj, load_file)) {
119  sdb_free(prj);
120  prj = NULL;
121  }
122 
123 return_goto:
124  rz_file_rm(tmp_file);
125  free(tmp_file);
126  return prj;
127 }
128 
130  sdb_free(prj);
131 }
132 
133 RZ_API RzProjectErr rz_project_load(RzCore *core, RzProject *prj, bool load_bin_io, RZ_NULLABLE const char *file, RzSerializeResultInfo *res) {
135  const char *type = sdb_const_get(prj, RZ_PROJECT_KEY_TYPE, 0);
136  if (!type || strcmp(type, RZ_PROJECT_TYPE) != 0) {
138  }
139  const char *version_str = sdb_const_get(prj, RZ_PROJECT_KEY_VERSION, 0);
140  if (!version_str) {
142  }
143  unsigned long version = strtoul(version_str, NULL, 0);
144  if (!version || version == ULONG_MAX) {
146  }
147  if (version > RZ_PROJECT_VERSION) {
149  }
150  if (!rz_project_migrate(prj, version, res)) {
152  }
153 
154  Sdb *core_db = sdb_ns(prj, "core", false);
155  if (!core_db) {
156  RZ_SERIALIZE_ERR(res, "missing core namespace");
158  }
159  if (!rz_serialize_core_load(core_db, core, load_bin_io, file, res)) {
161  }
162 
163  rz_config_set(core->config, "prj.file", file);
164 
165  return RZ_PROJECT_ERR_SUCCESS;
166 }
167 
168 RZ_API RzProjectErr rz_project_load_file(RzCore *core, const char *file, bool load_bin_io, RzSerializeResultInfo *res) {
170  if (!prj) {
171  RZ_SERIALIZE_ERR(res, "failed to read database file");
172  return RZ_PROJECT_ERR_FILE;
173  }
174  RzProjectErr ret = rz_project_load(core, prj, load_bin_io, file, res);
175  sdb_free(prj);
176  return ret;
177 }
static bool err
Definition: armass.c:435
int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
Definition: compress.c:68
RZ_API RzConfigNode * rz_config_set(RzConfig *cfg, RZ_NONNULL const char *name, const char *value)
Definition: config.c:267
#define RZ_API
#define NULL
Definition: cris-opc.c:27
static static fork const void static count close
Definition: sflib.h:33
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
int type
Definition: mipsasm.c:17
RZ_API Sdb * sdb_ns(Sdb *s, const char *name, int create)
Definition: ns.c:186
#define RZ_PROJECT_KEY_VERSION
Definition: project.c:7
RZ_API RzProjectErr rz_project_save(RzCore *core, RzProject *prj, const char *file)
Definition: project.c:35
RZ_API void rz_project_free(RzProject *prj)
Definition: project.c:129
#define RZ_PROJECT_KEY_TYPE
Definition: project.c:6
RZ_API RzProjectErr rz_project_load(RzCore *core, RzProject *prj, bool load_bin_io, RZ_NULLABLE const char *file, RzSerializeResultInfo *res)
Definition: project.c:133
RZ_API RZ_NONNULL const char * rz_project_err_message(RzProjectErr err)
Definition: project.c:11
RZ_API RzProjectErr rz_project_load_file(RzCore *core, const char *file, bool load_bin_io, RzSerializeResultInfo *res)
Definition: project.c:168
#define RZ_PROJECT_TYPE
Definition: project.c:9
RZ_API RzProjectErr rz_project_save_file(RzCore *core, const char *file, bool compress)
Definition: project.c:42
RZ_API RzProject * rz_project_load_file_raw(const char *file)
Load a file into an RzProject but don't actually migrate anything or load it into an RzCore.
Definition: project.c:88
RZ_API bool rz_project_migrate(RzProject *prj, unsigned long version, RzSerializeResultInfo *res)
Migrate the given project to the current version in-place.
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API bool rz_file_exists(const char *str)
Definition: file.c:192
RZ_API bool rz_file_is_deflated(RZ_NONNULL const char *src)
check whether a file is a deflated (gzip) file
Definition: file.c:1392
RZ_API bool rz_file_inflate(RZ_NONNULL const char *src, RZ_NONNULL const char *dst)
unzip the contents of src and store in dst
Definition: file.c:1361
RZ_API bool rz_file_deflate(RZ_NONNULL const char *src, RZ_NONNULL const char *dst)
zip the contents of src and store in dst
Definition: file.c:1329
RZ_API int rz_file_mkstemp(RZ_NULLABLE const char *prefix, char **oname)
Definition: file.c:1058
RZ_API bool rz_file_rm(const char *file)
Definition: file.c:865
@ RZ_PROJECT_ERR_MIGRATION_FAILED
Definition: rz_project.h:26
@ RZ_PROJECT_ERR_COMPRESSION_FAILED
Definition: rz_project.h:27
@ RZ_PROJECT_ERR_NEWER_VERSION
Definition: rz_project.h:24
@ RZ_PROJECT_ERR_SUCCESS
Definition: rz_project.h:20
@ RZ_PROJECT_ERR_INVALID_CONTENTS
Definition: rz_project.h:25
@ RZ_PROJECT_ERR_INVALID_TYPE
Definition: rz_project.h:22
@ RZ_PROJECT_ERR_FILE
Definition: rz_project.h:21
@ RZ_PROJECT_ERR_INVALID_VERSION
Definition: rz_project.h:23
@ RZ_PROJECT_ERR_UNKNOWN
Definition: rz_project.h:28
#define RZ_PROJECT_VERSION
Definition: rz_project.h:15
enum rz_project_err RzProjectErr
#define RZ_SERIALIZE_ERR(res,...)
Push an error to the local RzSerializeResultInfo \res RzSerializeInfoResult *.
Definition: rz_serialize.h:33
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_NONNULL
Definition: rz_types.h:64
RZ_API int sdb_set(Sdb *s, const char *key, const char *val, ut32 cas)
Definition: sdb.c:611
RZ_API Sdb * sdb_new0(void)
Definition: sdb.c:43
RZ_API bool sdb_free(Sdb *s)
Definition: sdb.c:206
RZ_API const char * sdb_const_get(Sdb *s, const char *key, ut32 *cas)
Definition: sdb.c:279
RZ_API bool sdb_text_save(Sdb *s, const char *file, bool sort)
Definition: text.c:199
RZ_API bool sdb_text_load(Sdb *s, const char *file)
Definition: text.c:405
RZ_API bool rz_serialize_core_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzCore *core, bool load_bin_io, RZ_NULLABLE const char *prj_file, RZ_NULLABLE RzSerializeResultInfo *res)
RZ_API void rz_serialize_core_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzCore *core, RZ_NULLABLE const char *prj_file)
Definition: gzappend.c:170
RzConfig * config
Definition: rz_core.h:300
Definition: sdb.h:63
static int file
Definition: z80asm.c:58