do not edit — generated by btf.
git.druid.rocksindexdruid520qsrc/db.c

src/db.c


#include "config.h"
 
#ifdef OS_NETBSD_C
#define _NETBSD_SOURCE 1
#endif
#define _POSIX_C_SOURCE 200809L
 
#include <string.h>
#include <dirent.h>
#include <sys/stat.h>
 
#include "q.h"
 
/* the installed-package database: <db>/<pkg>/ holding three files --
 * "name" (the package name), "ver" (its version), and "manifest" (one
 * prefix-relative path per line, the files that package owns). */
 
void
db_pkgdir(const char* db, const char* pkg, char* out, size_t max)
{
	if(pathjoin(out, max, db, pkg) == 0)
	{
		die("path too long");
		return;
	}
}
 
long
db_has(const char* db, const char* pkg)
{
	char pkgdir[MAXPATH];
	struct stat st;
 
	db_pkgdir(db, pkg, pkgdir, sizeof(pkgdir));
	if(lstat(pkgdir, &st) == 0 && S_ISDIR(st.st_mode))
	{
		return 1;
	}
	return 0;
}
 
void
db_install(const char* db, const char* pkg, const char* name, const char* ver,
    const struct snap* manifest)
{
	char pkgdir[MAXPATH];
	char fpath[MAXPATH];
	char buf[MAXVAL];
	size_t off;
 
	db_pkgdir(db, pkg, pkgdir, sizeof(pkgdir));
	makedirs(pkgdir);
 
	off = 0;
	if(bufcat(buf, sizeof(buf), &off, name) == 0
	    || bufcat(buf, sizeof(buf), &off, "\n") == 0)
	{
		die("pkg name too long");
		return;
	}
	if(pathjoin(fpath, sizeof(fpath), pkgdir, "name") == 0)
	{
		die("path too long");
		return;
	}
	if(writefile(fpath, buf, (long)off) < 0)
	{
		die("failed writing db name");
		return;
	}
 
	off = 0;
	if(bufcat(buf, sizeof(buf), &off, ver) == 0
	    || bufcat(buf, sizeof(buf), &off, "\n") == 0)
	{
		die("pkg version too long");
		return;
	}
	if(pathjoin(fpath, sizeof(fpath), pkgdir, "ver") == 0)
	{
		die("path too long");
		return;
	}
	if(writefile(fpath, buf, (long)off) < 0)
	{
		die("failed writing db version");
		return;
	}
 
	if(pathjoin(fpath, sizeof(fpath), pkgdir, "manifest") == 0)
	{
		die("path too long");
		return;
	}
	snap_writefile(manifest, fpath);
}
 
void
db_remove(const char* db, const char* pkg)
{
	char pkgdir[MAXPATH];
 
	db_pkgdir(db, pkg, pkgdir, sizeof(pkgdir));
	rmtree(pkgdir);
}
 
/* list every installed package's (name, ver) into out (key=name,
 * val=ver), in readdir order -- callers sort if they want deterministic
 * output. returns the count. a missing db is simply empty. */
long
db_list(const char* db, struct kv* out, long max)
{
	DIR* d;
	struct dirent* e;
	char pkgdir[MAXPATH];
	char fpath[MAXPATH];
	char buf[MAXVAL];
	struct stat st;
	long r;
	long n = 0;
 
	d = opendir(db);
	if(d == NULL)
	{
		return 0;
	}
	e = readdir(d);
	while(e != NULL && n < max)
	{
		if(e->d_name[0] != '.')
		{
			if(pathjoin(pkgdir, sizeof(pkgdir), db, e->d_name) == 0)
			{
				die("path too long");
				return n;
			}
			if(lstat(pkgdir, &st) == 0 && S_ISDIR(st.st_mode))
			{
				if(pathjoin(fpath, sizeof(fpath), pkgdir, "name") == 0)
				{
					die("path too long");
					return n;
				}
				r = readfile(fpath, buf, (long)sizeof(buf) - 1);
				if(r > 0)
				{
					size_t k;
 
					buf[r] = '\0';
					k = strlen(buf);
					while(k > 0 && (buf[k - 1] == '\n' || buf[k - 1] == '\r'))
					{
						buf[k - 1] = '\0';
						k = k - 1;
					}
					if(copystr(out[n].key, sizeof(out[n].key), buf) == 0)
					{
						die("pkg name too long");
						return n;
					}
				}
				else if(copystr(out[n].key, sizeof(out[n].key), e->d_name) == 0)
				{
					die("pkg name too long");
					return n;
				}
				if(pathjoin(fpath, sizeof(fpath), pkgdir, "ver") == 0)
				{
					die("path too long");
					return n;
				}
				r = readfile(fpath, buf, (long)sizeof(buf) - 1);
				if(r > 0)
				{
					size_t k;
 
					buf[r] = '\0';
					k = strlen(buf);
					while(k > 0 && (buf[k - 1] == '\n' || buf[k - 1] == '\r'))
					{
						buf[k - 1] = '\0';
						k = k - 1;
					}
					if(copystr(out[n].val, sizeof(out[n].val), buf) == 0)
					{
						die("pkg version too long");
						return n;
					}
				}
				else if(copystr(out[n].val, sizeof(out[n].val), "?") == 0)
				{
					die("pkg version too long");
					return n;
				}
				n = n + 1;
			}
		}
		e = readdir(d);
	}
	closedir(d);
	return n;
}
powered by btf.