osl logo

The lightweight storage library


[README] [Download] [INSTALL] [Quick Start] [API] [License] [Contact] [man page]
osltar.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009 Andre Noll <maan@tuebingen.mpg.de>
3  *
4  * Licensed under the GPL v2. For licencing details see COPYING.
5  */
6 
12 #include <inttypes.h>
13 #include <osl.h>
14 #include <string.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <dirent.h>
22 #include <errno.h>
23 #include <sys/mman.h>
24 #include <fcntl.h>
25 
34 };
35 
36 
41 #define __static__ static
42 
56 __static__ int string_compare(const struct osl_object *obj1, const struct osl_object *obj2)
57 {
58  const char *str1 = (const char *)obj1->data;
59  const char *str2 = (const char *)obj2->data;
60  return strcmp(str1, str2);
61 }
62 
63 static struct osl_column_description tar_table_cols[] = {
64  [OTC_NAME] = {
66  .storage_flags = OSL_RBTREE | OSL_UNIQUE,
67  .name = "filename",
68  .compare_function = string_compare,
69  },
70  [OTC_DATA] = {
71  .storage_type = OSL_MAPPED_STORAGE,
72  .storage_flags = 0,
73  .name = "data",
74  },
75 };
76 
77 static struct osl_table *table;
78 
79 static struct osl_table_description tar_table_desc = {
80  .name = "tar_table",
81  .num_columns = NUM_OT_COLUMNS,
82  .flags = 0,
83  .column_descriptions = tar_table_cols,
84 };
85 
86 static void print_usage_and_die(void)
87 {
88  fprintf(stderr, "usage:\n\tosltar c <db_dir> <data_dir>\n");
89  fprintf(stderr, "\tosltar x <db_dir> file1 [file2...]\n");
90  fprintf(stderr, "\tosltar t <db_dir>\n");
91  exit(EXIT_FAILURE);
92 }
93 
97 static int mmap_full_file(const char *path, void **map,
98  size_t *size)
99 {
100  int fd, ret, mmap_prot, mmap_flags;
101  struct stat file_status;
102 
103  mmap_prot = PROT_READ;
104  mmap_flags = MAP_PRIVATE;
105  ret = open(path, O_RDONLY, 0);
106  if (ret < 0) {
107  fprintf(stderr, "open: %s\n", strerror(errno));
108  return ret;
109  }
110  fd = ret;
111  if (fstat(fd, &file_status) < 0) {
112  ret = -1;
113  fprintf(stderr, "fstat: %s\n", strerror(errno));
114  goto out;
115  }
116  *size = file_status.st_size;
117  if (!*size) {
118  fprintf(stderr, "can not add empty file: %s\n", path);
119  goto out;
120  }
121  *map = mmap(NULL, *size, mmap_prot, mmap_flags, fd, 0);
122  if (*map == MAP_FAILED) {
123  fprintf(stderr, "map failed: %s\n", path);
124  *map = NULL;
125  goto out;
126  }
127  ret = 1;
128 out:
129  close(fd);
130  return ret;
131 }
132 
133 
134 static int add_file(char *name)
135 {
136  int ret;
137  struct osl_object objs[NUM_OT_COLUMNS] = {
138  [OTC_NAME] = {
139  .data = name,
140  .size = strlen(name) + 1
141  },
142  };
143  printf("%s\n", name);
144  ret = mmap_full_file(name, &objs[OTC_DATA].data,
145  &objs[OTC_DATA].size);
146  if (ret < 0)
147  return ret;
148  return osl_add_row(table, objs);
149 }
150 
151 static int populate_table(const char *dirname)
152 {
153  struct dirent *entry;
154  DIR *dir;
155  int ret = chdir(dirname);
156 
157  if (ret < 0) {
158  fprintf(stderr, "chdir: %s\n", strerror(errno));
159  exit(EXIT_FAILURE);
160  }
161  dir = opendir(".");
162  if (!dir) {
163  fprintf(stderr, "opendir: %s\n", strerror(errno));
164  exit(EXIT_FAILURE);
165  }
166  while ((entry = readdir(dir))) {
167  mode_t m;
168  struct stat s;
169 
170  if (!strcmp(entry->d_name, "."))
171  continue;
172  if (!strcmp(entry->d_name, ".."))
173  continue;
174  if (lstat(entry->d_name, &s) == -1)
175  continue;
176  m = s.st_mode;
177  if (!S_ISREG(m))
178  continue;
179  ret = add_file(entry->d_name);
180  if (ret < 0)
181  goto out;
182  }
183  ret = 1;
184 out:
185  closedir(dir);
186  return ret;
187 }
188 
189 static int com_create(int argc, char **argv)
190 {
191  struct stat statbuf;
192  int ret;
193 
194  if (argc != 3)
195  print_usage_and_die();
196  if (lstat(argv[2], &statbuf) == -1) {
197  fprintf(stderr, "no such dir: %s\n", argv[2]);
198  exit(EXIT_FAILURE);
199  }
200  if (!S_ISDIR(statbuf.st_mode)) {
201  fprintf(stderr, "not a dir: %s\n", argv[2]);
202  exit(EXIT_FAILURE);
203  }
204  tar_table_desc.dir = argv[1];
205  ret = osl_create_table(&tar_table_desc);
206  if (ret < 0) {
207  fprintf(stderr, "failed to create table\n");
208  exit(EXIT_FAILURE);
209 
210  }
211  ret = osl_open_table(&tar_table_desc, &table);
212  if (ret < 0) {
213  fprintf(stderr, "osl_open_table: %s\n", osl_strerror(-ret));
214  exit(EXIT_FAILURE);
215  }
216  ret = populate_table(argv[2]);
218  return ret < 0? EXIT_FAILURE : EXIT_SUCCESS;
219 }
220 
224 static ssize_t write_all(int fd, const void *buf, size_t size)
225 {
226  const char *b = buf;
227  while (size) {
228  ssize_t ret = write(fd, b, size);
229  if (ret < 0) {
230  fprintf(stderr, "open: %s\n", strerror(errno));
231  return ret;
232 
233  }
234  b += ret;
235  size -= ret;
236  }
237  return 1;
238 }
239 
243 static int write_file(const char *filename, const void *buf, size_t size)
244 {
245  int ret, fd;
246 
247  ret = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0644);
248  if (ret < 0) {
249  fprintf(stderr, "open: %s\n", strerror(errno));
250  return ret;
251 
252  }
253  fd = ret;
254  printf("%s\n", filename);
255  ret = write_all(fd, buf, size);
256  if (ret < 0)
257  goto out;
258  ret = 1;
259 out:
260  close(fd);
261  return ret;
262 }
263 
264 static int extract_file(char *name)
265 {
266  int ret;
267  struct osl_row *row;
268  struct osl_object obj = {.data = name, .size = strlen(name) + 1};
269 
270  ret = osl_get_row(table, OTC_NAME, &obj, &row);
271  if (ret < 0) {
272  fprintf(stderr, "osl_get_row(%s): %s\n", name,
273  osl_strerror(-ret));
274  return ret;
275  }
276  ret = osl_get_object(table, row, OTC_DATA, &obj);
277  if (ret < 0) {
278  fprintf(stderr, "osl_get_object: %s\n", osl_strerror(-ret));
279  return ret;
280  }
281  return write_file(name, obj.data, obj.size);
282 }
283 
284 static int com_extract(int argc, char **argv)
285 {
286  int i, ret;
287 
288  if (argc < 3)
289  print_usage_and_die();
290  tar_table_desc.dir = argv[1];
291  ret = osl_open_table(&tar_table_desc, &table);
292  if (ret < 0) {
293  fprintf(stderr, "osl_open_table: %s\n", osl_strerror(-ret));
294  exit(EXIT_FAILURE);
295 
296  }
297  for (i = 2; i < argc; i++) {
298  ret = extract_file(argv[i]);
299  if (ret < 0)
300  goto out;
301  }
302 out:
304  return ret;
305 }
306 
307 static int list_entry(struct osl_row *row, void *data)
308 {
309  struct osl_object obj;
310  int ret = osl_get_object(table, row, OTC_NAME, &obj);
311  if (ret < 0) {
312  fprintf(stderr, "osl_get_object: %s\n", osl_strerror(-ret));
313  return ret;
314  }
315  printf("%s\n", (char *)obj.data);
316  return 1;
317 }
318 
319 static int com_list(int argc, char **argv)
320 {
321  int ret;
322 
323  if (argc != 2)
324  print_usage_and_die();
325  tar_table_desc.dir = argv[1];
326  ret = osl_open_table(&tar_table_desc, &table);
327  if (ret < 0) {
328  fprintf(stderr, "osl_open_table: %s\n", osl_strerror(-ret));
329  exit(EXIT_FAILURE);
330 
331  }
332  ret = osl_rbtree_loop(table, OTC_NAME, NULL, list_entry);
334  return ret;
335 }
336 
343 int main(int argc, char **argv)
344 {
345  if (argc < 2)
346  print_usage_and_die();
347  if (!strcmp(argv[1], "c"))
348  return com_create(argc - 1, argv + 1);
349  if (!strcmp(argv[1], "x"))
350  return com_extract(argc - 1, argv + 1);
351  if (!strcmp(argv[1], "t"))
352  return com_list(argc - 1, argv + 1);
353  print_usage_and_die();
354  exit(EXIT_FAILURE);
355 
356 }
Definition: osl.h:68
Definition: osl.h:64
int osl_add_row(struct osl_table *t, struct osl_object *objects)
int osl_rbtree_loop(const struct osl_table *t, unsigned col_num, void *private_data, osl_rbtree_loop_func *func)
size_t size
Definition: osl.h:22
int osl_close_table(struct osl_table *t, enum osl_close_flags flags)
osltar_columns
Definition: osltar.c:27
int osl_get_object(const struct osl_table *t, const struct osl_row *row, unsigned col_num, struct osl_object *object)
int main(int argc, char **argv)
Definition: osltar.c:343
void * data
Definition: osl.h:20
const char * name
Definition: osl.h:146
const char * osl_strerror(int num)
uint16_t storage_type
Definition: osl.h:101
__static__ int string_compare(const struct osl_object *obj1, const struct osl_object *obj2)
Definition: osltar.c:56
int osl_open_table(const struct osl_table_description *desc, struct osl_table **result)
int osl_get_row(const struct osl_table *t, unsigned col_num, const struct osl_object *obj, struct osl_row **result)
int osl_create_table(const struct osl_table_description *desc)
Definition: osl.h:18
const char * dir
Definition: osl.h:140