mirror of
https://github.com/pygos/pkg-utils.git
synced 2024-05-18 04:06:15 +02:00
131 lines
2.1 KiB
C
131 lines
2.1 KiB
C
|
#include "pack.h"
|
||
|
|
||
|
static const struct {
|
||
|
const char *name;
|
||
|
image_entry_t *(*handle)(input_file_t *f);
|
||
|
} line_hooks[] = {
|
||
|
{ "file", filelist_mkfile },
|
||
|
{ "dir", filelist_mkdir },
|
||
|
{ "slink", filelist_mkslink },
|
||
|
};
|
||
|
|
||
|
#define NUM_LINE_HOOKS (sizeof(line_hooks) / sizeof(line_hooks[0]))
|
||
|
|
||
|
static int prefetch_line(input_file_t *f)
|
||
|
{
|
||
|
char *line = NULL;
|
||
|
size_t n = 0;
|
||
|
ssize_t ret;
|
||
|
|
||
|
free(f->line);
|
||
|
f->line = NULL;
|
||
|
|
||
|
errno = 0;
|
||
|
ret = getline(&line, &n, f->f);
|
||
|
|
||
|
if (ret < 0) {
|
||
|
if (errno != 0) {
|
||
|
perror(f->filename);
|
||
|
free(line);
|
||
|
return -1;
|
||
|
}
|
||
|
free(line);
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
n = strlen(line);
|
||
|
while (n >0 && isspace(line[n - 1]))
|
||
|
--n;
|
||
|
line[n] = '\0';
|
||
|
|
||
|
f->line = line;
|
||
|
f->linenum += 1;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static void cleanup_file(input_file_t *f)
|
||
|
{
|
||
|
fclose(f->f);
|
||
|
free(f->line);
|
||
|
}
|
||
|
|
||
|
static int open_file(input_file_t *f, const char *filename)
|
||
|
{
|
||
|
memset(f, 0, sizeof(*f));
|
||
|
|
||
|
f->filename = filename;
|
||
|
f->f = fopen(filename, "r");
|
||
|
|
||
|
if (f->f == NULL) {
|
||
|
perror(f->filename);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
image_entry_t *filelist_read(const char *filename)
|
||
|
{
|
||
|
image_entry_t *ent, *list = NULL;
|
||
|
input_file_t f;
|
||
|
size_t i, len;
|
||
|
char *ptr;
|
||
|
int ret;
|
||
|
|
||
|
if (open_file(&f, filename))
|
||
|
return NULL;
|
||
|
|
||
|
for (;;) {
|
||
|
ret = prefetch_line(&f);
|
||
|
if (ret < 0)
|
||
|
goto fail;
|
||
|
if (ret > 0)
|
||
|
break;
|
||
|
|
||
|
for (ptr = f.line; isspace(*ptr); ++ptr)
|
||
|
;
|
||
|
|
||
|
if (*ptr == '\0' || *ptr == '#')
|
||
|
continue;
|
||
|
|
||
|
for (i = 0; i < NUM_LINE_HOOKS; ++i) {
|
||
|
len = strlen(line_hooks[i].name);
|
||
|
|
||
|
if (strncmp(ptr, line_hooks[i].name, len) != 0)
|
||
|
continue;
|
||
|
if (!isspace(ptr[len]) && ptr[len] != '\0')
|
||
|
continue;
|
||
|
for (ptr += len; isspace(*ptr); ++ptr)
|
||
|
;
|
||
|
memmove(f.line, ptr, strlen(ptr) + 1);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (i == NUM_LINE_HOOKS) {
|
||
|
fprintf(stderr, "%s: %zu: unknown entry type\n",
|
||
|
f.filename, f.linenum);
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
ent = line_hooks[i].handle(&f);
|
||
|
if (ent == NULL)
|
||
|
goto fail;
|
||
|
|
||
|
ent->next = list;
|
||
|
list = ent;
|
||
|
}
|
||
|
|
||
|
if (list == NULL) {
|
||
|
fprintf(stderr, "%s: does not contain any entries\n",
|
||
|
f.filename);
|
||
|
goto fail;
|
||
|
}
|
||
|
|
||
|
cleanup_file(&f);
|
||
|
return list;
|
||
|
fail:
|
||
|
cleanup_file(&f);
|
||
|
image_entry_free_list(list);
|
||
|
return NULL;
|
||
|
}
|