summaryrefslogtreecommitdiffstats
path: root/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'common.c')
-rw-r--r--common.c110
1 files changed, 110 insertions, 0 deletions
diff --git a/common.c b/common.c
new file mode 100644
index 0000000..58d45ee
--- /dev/null
+++ b/common.c
@@ -0,0 +1,110 @@
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include "common.h"
+
+char *table_name_to_file(const char *name) {
+
+ char *share_path = getenv("SHARE_PATH");
+ char *fname;
+ if (!share_path || !*share_path) share_path = "/usr/share";
+
+ asprintf(&fname, "%s/ldetect-lst/%s", share_path, name);
+
+ return fname;
+}
+
+fh fh_open(const char *name) {
+ fh ret;
+ char *fname = table_name_to_file(name);
+
+ if (access(fname, R_OK) == 0) {
+ /* prefer gzip type when not compressed, more direct than zlib access */
+ ret.gztype = GZIP;
+ ret.u.gzip_fh.f = fopen(fname, "r");
+ ret.u.gzip_fh.pid = 0;
+ } else {
+ char *fname_gz;
+ asprintf(&fname_gz, "%s.gz", fname);
+ if (access(GZIP_BIN, R_OK) == 0) {
+ int fdno[2];
+ ret.gztype = GZIP;
+ if (access(fname_gz, R_OK) != 0) {
+ fprintf(stderr, "Missing %s (should be %s)\n", name, fname);
+ exit(1);
+ }
+ if (pipe(fdno)) {
+ perror("pciusb");
+ exit(1);
+ }
+
+ if ((ret.u.gzip_fh.pid = fork()) != 0) {
+ ret.u.gzip_fh.f = fdopen(fdno[0], "r");
+ close(fdno[1]);
+ } else {
+ char* cmd[5];
+ int ip = 0;
+ char *ld_loader = getenv("LD_LOADER");
+
+ if (ld_loader && *ld_loader)
+ cmd[ip++] = ld_loader;
+
+ cmd[ip++] = GZIP_BIN;
+ cmd[ip++] = "-cd";
+ cmd[ip++] = fname_gz;
+ cmd[ip++] = NULL;
+
+ dup2(fdno[1], STDOUT_FILENO);
+ close(fdno[0]);
+ close(fdno[1]);
+ execvp(cmd[0], cmd);
+ perror("pciusb");
+ exit(2);
+ }
+ } else {
+ ret.gztype = ZLIB;
+ ret.u.zlib_fh = gzopen(fname_gz, "r");
+ if (!ret.u.zlib_fh) {
+ perror("pciusb");
+ exit(3);
+ }
+ }
+ free(fname_gz);
+ }
+
+ free(fname);
+ return ret;
+}
+
+char* fh_gets(char *line, int size, fh *f) {
+ char *ret = NULL;
+ switch (f->gztype) {
+ case ZLIB:
+ ret = gzgets(f->u.zlib_fh, line, size);
+ break;
+ case GZIP:
+ ret = fgets(line, size, f->u.gzip_fh.f);
+ break;
+ }
+ return ret;
+}
+
+int fh_close(fh *f) {
+ int ret = EOF;
+ switch (f->gztype) {
+ case ZLIB:
+ ret = gzclose(f->u.zlib_fh);
+ break;
+ case GZIP:
+ ret = fclose(f->u.gzip_fh.f);
+ if (f->u.gzip_fh.pid > 0)
+ waitpid(f->u.gzip_fh.pid, NULL, 0);
+ break;
+ }
+ return ret;
+}