static struct sbuf * read_input(void) { struct sbuf *input; int ch; input = sbuf_new_auto(); for (;;) { ch = getc(stdin); if (ch == EOF) { if (feof(stdin)) break; if (ferror(stdin)) err(EX_NOINPUT, "Failed to read stdin"); } sbuf_putc(input, ch); } #ifdef __DragonFly__ sbuf_finish(input); #else if (sbuf_finish(input) != 0) err(EX_DATAERR, "Could not read value data"); #endif return (input); }
/* construct path to node->name */ static char * mtree_file_path(fsnode *node) { fsnode *pnode; struct sbuf *sb; char *res, *rp[MAKEFS_MAX_TREE_DEPTH]; int depth; depth = 0; rp[depth] = node->name; for (pnode = node->parent; pnode && depth < MAKEFS_MAX_TREE_DEPTH; pnode = pnode->parent) { if (strcmp(pnode->name, ".") == 0) break; rp[++depth] = pnode->name; } sb = sbuf_new_auto(); if (sb == NULL) { errno = ENOMEM; return (NULL); } while (depth > 0) { sbuf_cat(sb, rp[depth--]); sbuf_putc(sb, '/'); } sbuf_cat(sb, rp[depth]); sbuf_finish(sb); res = strdup(sbuf_data(sb)); sbuf_delete(sb); if (res == NULL) errno = ENOMEM; return res; }
void vfs_mountroot(void) { struct mount *mp; struct sbuf *sb; struct thread *td; time_t timebase; int error; td = curthread; vfs_mountroot_wait(); sb = sbuf_new_auto(); vfs_mountroot_conf0(sb); sbuf_finish(sb); error = vfs_mountroot_devfs(td, &mp); while (!error) { error = vfs_mountroot_parse(sb, mp); if (!error) { error = vfs_mountroot_shuffle(td, mp); if (!error) { sbuf_clear(sb); error = vfs_mountroot_readconf(td, sb); sbuf_finish(sb); } } } sbuf_delete(sb); /* * Iterate over all currently mounted file systems and use * the time stamp found to check and/or initialize the RTC. * Call inittodr() only once and pass it the largest of the * timestamps we encounter. */ timebase = 0; mtx_lock(&mountlist_mtx); mp = TAILQ_FIRST(&mountlist); while (mp != NULL) { if (mp->mnt_time > timebase) timebase = mp->mnt_time; mp = TAILQ_NEXT(mp, mnt_list); } mtx_unlock(&mountlist_mtx); inittodr(timebase); /* Keep prison0's root in sync with the global rootvnode. */ mtx_lock(&prison0.pr_mtx); prison0.pr_root = rootvnode; vref(prison0.pr_root); mtx_unlock(&prison0.pr_mtx); mtx_lock(&mountlist_mtx); atomic_store_rel_int(&root_mount_complete, 1); wakeup(&root_mount_complete); mtx_unlock(&mountlist_mtx); }
static void khttpd_ktr_logging_main(void *arg) { struct sbuf *sbuf; struct thread *td; int error; KHTTPD_ASSERT_CURPROC_IS_KHTTPD(); td = curthread; khttpd_ktr_logging_idx = ktr_idx; error = kern_openat(td, AT_FDCWD, KHTTPD_KTR_FILE, UIO_SYSSPACE, O_CREAT | O_TRUNC | O_WRONLY, 0666); if (error != 0) { log(LOG_WARNING, "khttpd: failed to open ktr file '%s' " "(error %d)", KHTTPD_KTR_FILE, error); goto quit; } kern_close(td, td->td_retval[0]); sbuf = sbuf_new_auto(); while (!khttpd_ktr_logging_shutdown) { khttpd_ktr_logging(sbuf); pause("khttpd-ktr-flush", hz); } sbuf_delete(sbuf); quit: khttpd_ktr_logging_thread = NULL; kthread_exit(); }
void sbuf_init(struct sbuf **buf) { if (*buf == NULL) *buf = sbuf_new_auto(); else sbuf_clear(*buf); }
int pkg_script_run(struct pkg *pkg, pkg_script_t type) { struct pkg_script *script = NULL; pkg_script_t stype; struct sbuf *script_cmd = sbuf_new_auto(); size_t i; struct { const char *arg; const pkg_script_t b; const pkg_script_t a; } const map[] = { /* a implies b with argument arg */ {"PRE-INSTALL", PKG_SCRIPT_INSTALL, PKG_SCRIPT_PRE_INSTALL}, {"POST-INSTALL", PKG_SCRIPT_INSTALL, PKG_SCRIPT_POST_INSTALL}, {"PRE-UPGRADE", PKG_SCRIPT_UPGRADE, PKG_SCRIPT_PRE_UPGRADE}, {"POST-UPGRADE", PKG_SCRIPT_UPGRADE, PKG_SCRIPT_POST_UPGRADE}, {"DEINSTALL", PKG_SCRIPT_DEINSTALL, PKG_SCRIPT_PRE_DEINSTALL}, {"POST-DEINSTALL", PKG_SCRIPT_DEINSTALL, PKG_SCRIPT_POST_DEINSTALL}, }; for (i = 0; i < sizeof(map) / sizeof(map[0]); i++) { if (map[i].a == type) break; } if (map[i].a != type) return (ERROR_BAD_ARG("type")); while (pkg_scripts(pkg, &script) == EPKG_OK) { stype = pkg_script_type(script); if (stype == map[i].a || stype == map[i].b) { sbuf_reset(script_cmd); sbuf_printf(script_cmd, "PKG_PREFIX=%s\nset -- %s-%s", pkg_get(pkg, PKG_PREFIX), pkg_get(pkg, PKG_NAME), pkg_get(pkg, PKG_VERSION)); if (stype == map[i].b) { /* add arg **/ sbuf_cat(script_cmd, " "); sbuf_cat(script_cmd, map[i].arg); } sbuf_cat(script_cmd, "\n"); sbuf_cat(script_cmd, pkg_script_data(script)); sbuf_finish(script_cmd); system(sbuf_data(script_cmd)); } } sbuf_delete(script_cmd); return (EPKG_OK); }
int pkg_delete(struct pkg *pkg, struct pkgdb *db, int force) { struct pkg **rdeps; int i, ret; struct sbuf *rdep_msg; if (pkg == NULL) return (ERROR_BAD_ARG("pkg")); if (db == NULL) return (ERROR_BAD_ARG("db")); /* * Ensure that we have all the informations we need */ if ((ret = pkgdb_loadrdeps(db, pkg)) != EPKG_OK) return (ret); if ((ret = pkgdb_loadfiles(db, pkg)) != EPKG_OK) return (ret); if ((ret = pkgdb_loadscripts(db, pkg)) != EPKG_OK) return (ret); if ((ret = pkgdb_loadmtree(db, pkg)) != EPKG_OK) return (ret); rdeps = pkg_rdeps(pkg); if (rdeps[0] != NULL) { rdep_msg = sbuf_new_auto(); sbuf_printf(rdep_msg, "%s-%s is required by other packages:", pkg_get(pkg, PKG_NAME), pkg_get(pkg, PKG_VERSION)); for (i = 0;rdeps[i] != NULL; i++) { sbuf_cat(rdep_msg, " "); sbuf_printf(rdep_msg, "%s-%s", pkg_get(rdeps[i], PKG_NAME), pkg_get(rdeps[i], PKG_VERSION)); } if (!force) { sbuf_finish(rdep_msg); ret = pkg_error_set(EPKG_REQUIRED, "%s", sbuf_get(rdep_msg)); sbuf_free(rdep_msg); return ret; } sbuf_cat(rdep_msg, ", deleting anyway"); sbuf_finish(rdep_msg); fprintf(stderr, "%s\n", sbuf_get(rdep_msg)); sbuf_free(rdep_msg); } if ((ret = pkg_script_pre_deinstall(pkg)) != EPKG_OK) return (ret); if ((ret = pkg_delete_files(pkg, force)) != EPKG_OK) return (ret); if ((ret = pkg_script_post_deinstall(pkg)) != EPKG_OK) return (ret); return (pkgdb_unregister_pkg(db, pkg_get(pkg, PKG_ORIGIN))); }
int exec_add(int argc, char **argv) { struct pkgdb *db = NULL; struct sbuf *failedpkgs = sbuf_new_auto(); char path[MAXPATHLEN + 1]; char *file; int retcode = EPKG_OK; int i; int failedpkgcount = 0; struct pkg *p = NULL; if (argc < 2) { usage_add(); return (EX_USAGE); } if (geteuid() != 0) { warnx("adding packages can only be done as root"); return (EX_NOPERM); } if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { return (EX_IOERR); } for (i = 1; i < argc; i++) { if (is_url(argv[i]) == EPKG_OK) { snprintf(path, sizeof(path), "./%s", basename(argv[i])); if ((retcode = pkg_fetch_file(argv[i], path)) != EPKG_OK) break; file = path; } else file = argv[i]; pkg_open(&p, file, NULL); if ((retcode = pkg_add(db, file, 0)) != EPKG_OK) { sbuf_cat(failedpkgs, argv[i]); if (i != argc - 1) sbuf_printf(failedpkgs, ", "); failedpkgcount++; } } pkgdb_close(db); if(failedpkgcount > 0) { sbuf_finish(failedpkgs); printf("Failed to install the following %d package(s): %s.\n", failedpkgcount, sbuf_data(failedpkgs)); } sbuf_delete(failedpkgs); return (retcode == EPKG_OK ? EX_OK : EX_SOFTWARE); }
struct pkgdb_it * pkgdb_rquery_provide(struct pkgdb *db, const char *provide, const char *repo) { sqlite3_stmt *stmt; struct sbuf *sql = NULL; const char *reponame = NULL; int ret; const char basesql[] = "" "SELECT p.id, p.origin, p.name, p.version, p.comment, " "p.name || '~' || p.origin as uniqueid, " "p.prefix, p.desc, p.arch, p.maintainer, p.www, " "p.licenselogic, p.flatsize, p.pkgsize, " "p.cksum, p.manifestdigest, p.path AS repopath, '%1$s' AS dbname " "FROM '%1$s'.packages AS p, '%1$s'.pkg_provides AS pp, " "'%1$s'.provides AS pr " "WHERE p.id = pp.package_id " "AND pp.provide_id = pr.id " "AND pr.name = ?1;"; assert(db != NULL); reponame = pkgdb_get_reponame(db, repo); sql = sbuf_new_auto(); /* * Working on multiple remote repositories */ if (reponame == NULL) { /* duplicate the query via UNION for all the attached * databases */ ret = pkgdb_sql_all_attached(db->sqlite, sql, basesql, " UNION ALL "); if (ret != EPKG_OK) { sbuf_delete(sql); return (NULL); } } else sbuf_printf(sql, basesql, reponame); sbuf_finish(sql); pkg_debug(4, "Pkgdb: running '%s'", sbuf_get(sql)); ret = sqlite3_prepare_v2(db->sqlite, sbuf_get(sql), -1, &stmt, NULL); if (ret != SQLITE_OK) { ERROR_SQLITE(db->sqlite, sbuf_get(sql)); sbuf_delete(sql); return (NULL); } sbuf_delete(sql); sqlite3_bind_text(stmt, 1, provide, -1, SQLITE_TRANSIENT); return (pkgdb_it_new(db, stmt, PKG_REMOTE, PKGDB_IT_FLAG_ONCE)); }
int format_exec_cmd(char **dest, const char *in, const char *prefix, const char *plist_file) { struct sbuf *buf = sbuf_new_auto(); char path[MAXPATHLEN + 1]; char *cp; while (in[0] != '\0') { if (in[0] == '%') { in++; switch(in[0]) { case 'D': sbuf_cat(buf, prefix); break; case 'F': sbuf_cat(buf, plist_file); break; case 'f': if (prefix[strlen(prefix) - 1] == '/') snprintf(path, sizeof(path), "%s%s", prefix, plist_file); else snprintf(path, sizeof(path), "%s/%s", prefix, plist_file); cp = strrchr(path, '/'); cp ++; sbuf_cat(buf, cp); break; case 'B': if (prefix[strlen(prefix) - 1] == '/') snprintf(path, sizeof(path), "%s%s", prefix, plist_file); else snprintf(path, sizeof(path), "%s/%s", prefix, plist_file); cp = strrchr(path, '/'); cp[0] = '\0'; sbuf_cat(buf, path); break; default: sbuf_putc(buf, in[0]); break; } } else { sbuf_putc(buf, in[0]); } in++; } sbuf_finish(buf); *dest = strdup(sbuf_data(buf)); sbuf_free(buf); return (0); }
int packing_append_tree(struct packing *pack, const char *treepath, const char *newroot) { FTS *fts = NULL; FTSENT *fts_e = NULL; size_t treelen; struct sbuf *sb; char *paths[2] = { __DECONST(char *, treepath), NULL }; treelen = strlen(treepath); fts = fts_open(paths, FTS_PHYSICAL | FTS_XDEV, NULL); if (fts == NULL) goto cleanup; sb = sbuf_new_auto(); while ((fts_e = fts_read(fts)) != NULL) { switch(fts_e->fts_info) { case FTS_D: case FTS_DEFAULT: case FTS_F: case FTS_SL: case FTS_SLNONE: /* Entries not within this tree are irrelevant. */ if (fts_e->fts_pathlen <= treelen) break; sbuf_clear(sb); /* Strip the prefix to obtain the target path */ if (newroot) /* Prepend a root if one is specified */ sbuf_cat(sb, newroot); /* +1 = skip trailing slash */ sbuf_cat(sb, fts_e->fts_path + treelen + 1); sbuf_finish(sb); packing_append_file(pack, fts_e->fts_name, sbuf_get(sb)); break; case FTS_DC: case FTS_DNR: case FTS_ERR: case FTS_NS: /* XXX error cases, check fts_e->fts_errno and * bubble up the call chain */ break; default: break; } } sbuf_free(sb); cleanup: fts_close(fts); return EPKG_OK; }
int sbuf_set(struct sbuf **buf, const char *str) { if (*buf == NULL) *buf = sbuf_new_auto(); if (str == NULL) return (-1); sbuf_cpy(*buf, str); sbuf_finish(*buf); return (0); }
int64_t pkg_repo_binary_stat(struct pkg_repo *repo, pkg_stats_t type) { sqlite3 *sqlite = PRIV_GET(repo); sqlite3_stmt *stmt = NULL; int64_t stats = 0; struct sbuf *sql = NULL; int ret; sql = sbuf_new_auto(); switch(type) { case PKG_STATS_LOCAL_COUNT: goto out; break; case PKG_STATS_LOCAL_SIZE: goto out; break; case PKG_STATS_REMOTE_UNIQUE: sbuf_printf(sql, "SELECT COUNT(id) FROM main.packages;"); break; case PKG_STATS_REMOTE_COUNT: sbuf_printf(sql, "SELECT COUNT(id) FROM main.packages;"); break; case PKG_STATS_REMOTE_SIZE: sbuf_printf(sql, "SELECT SUM(pkgsize) FROM main.packages;"); break; case PKG_STATS_REMOTE_REPOS: goto out; break; } sbuf_finish(sql); pkg_debug(4, "binary_repo: running '%s'", sbuf_data(sql)); ret = sqlite3_prepare_v2(sqlite, sbuf_data(sql), -1, &stmt, NULL); if (ret != SQLITE_OK) { ERROR_SQLITE(sqlite, sbuf_data(sql)); goto out; } while (sqlite3_step(stmt) != SQLITE_DONE) { stats = sqlite3_column_int64(stmt, 0); } out: sbuf_free(sql); if (stmt != NULL) sqlite3_finalize(stmt); return (stats); }
void khttpd_ktr_logging_fini(void) { struct sbuf *sbuf; KHTTPD_ASSERT_CURPROC_IS_KHTTPD(); khttpd_ktr_logging_shutdown = TRUE; while (khttpd_ktr_logging_thread != NULL) pause("khttpd-ktr-flush-fini", hz); sbuf = sbuf_new_auto(); khttpd_ktr_logging(sbuf); sbuf_delete(sbuf); }
/*------- API comments for these methods can be found in xenstorevar.h -------*/ struct sbuf * xs_join(const char *dir, const char *name) { struct sbuf *sb; sb = sbuf_new_auto(); sbuf_cat(sb, dir); if (name[0] != '\0') { sbuf_putc(sb, '/'); sbuf_cat(sb, name); } sbuf_finish(sb); return (sb); }
struct pkg_repo_it * pkg_repo_binary_query(struct pkg_repo *repo, const char *pattern, match_t match) { sqlite3 *sqlite = PRIV_GET(repo); sqlite3_stmt *stmt = NULL; struct sbuf *sql = NULL; const char *comp = NULL; int ret; char basesql[BUFSIZ] = "" "SELECT id, origin, name, name as uniqueid, version, comment, " "prefix, desc, arch, maintainer, www, " "licenselogic, flatsize, pkgsize, " "cksum, manifestdigest, path AS repopath, '%s' AS dbname " "FROM packages AS p"; if (match != MATCH_ALL && (pattern == NULL || pattern[0] == '\0')) return (NULL); sql = sbuf_new_auto(); comp = pkgdb_get_pattern_query(pattern, match); if (comp && comp[0]) strlcat(basesql, comp, sizeof(basesql)); sbuf_printf(sql, basesql, repo->name); sbuf_cat(sql, " ORDER BY name;"); sbuf_finish(sql); pkg_debug(4, "Pkgdb: running '%s' query for %s", sbuf_data(sql), pattern == NULL ? "all": pattern); ret = sqlite3_prepare_v2(sqlite, sbuf_data(sql), sbuf_len(sql), &stmt, NULL); if (ret != SQLITE_OK) { ERROR_SQLITE(sqlite, sbuf_data(sql)); sbuf_delete(sql); return (NULL); } sbuf_delete(sql); if (match != MATCH_ALL && match != MATCH_CONDITION) sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_TRANSIENT); return (pkg_repo_binary_it_new(repo, stmt, PKGDB_IT_FLAG_ONCE)); }
struct pkg_repo_it * pkg_repo_binary_search(struct pkg_repo *repo, const char *pattern, match_t match, pkgdb_field field, pkgdb_field sort) { sqlite3 *sqlite = PRIV_GET(repo); sqlite3_stmt *stmt = NULL; struct sbuf *sql = NULL; int ret; const char *multireposql = "" "SELECT id, origin, name, version, comment, " "prefix, desc, arch, maintainer, www, " "licenselogic, flatsize, pkgsize, " "cksum, path AS repopath, '%1$s' AS dbname, '%2$s' AS repourl " "FROM packages "; if (pattern == NULL || pattern[0] == '\0') return (NULL); sql = sbuf_new_auto(); sbuf_printf(sql, multireposql, repo->name, repo->url); /* close the UNIONs and build the search query */ sbuf_cat(sql, "WHERE "); pkg_repo_binary_build_search_query(sql, match, field, sort); sbuf_cat(sql, ";"); sbuf_finish(sql); pkg_debug(4, "Pkgdb: running '%s'", sbuf_data(sql)); ret = sqlite3_prepare_v2(sqlite, sbuf_data(sql), -1, &stmt, NULL); if (ret != SQLITE_OK) { ERROR_SQLITE(sqlite, sbuf_data(sql)); sbuf_delete(sql); return (NULL); } sbuf_delete(sql); sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_TRANSIENT); return (pkg_repo_binary_it_new(repo, stmt, PKGDB_IT_FLAG_ONCE)); }
static int urlencode(const char *src, struct sbuf **dest) { size_t len; size_t i; if (*dest == NULL) *dest = sbuf_new_auto(); else sbuf_clear(*dest); len = strlen(src); for (i = 0; i < len; i++) { if (!isascii(src[i]) || src[i] == '%') sbuf_printf(*dest, "%%%.2x", (unsigned char)src[i]); else sbuf_putc(*dest, src[i]); } sbuf_finish(*dest); return (EPKG_OK); }
static int urldecode(const char *src, struct sbuf **dest) { size_t len; size_t i; char c; char hex[] = {'\0', '\0', '\0'}; if (*dest == NULL) *dest = sbuf_new_auto(); else sbuf_reset(*dest); len = strlen(src); for (i = 0; i < len; i++) { if (src[i] != '%') { sbuf_putc(*dest, src[i]); } else { if (i + 2 > len) { pkg_emit_error("unexpected end of string"); return (EPKG_FATAL); } hex[0] = src[++i]; hex[1] = src[++i]; errno = 0; c = strtol(hex, NULL, 16); if (errno != 0) { pkg_emit_errno("strtol()", hex); return (EPKG_FATAL); } sbuf_putc(*dest, c); } } sbuf_finish(*dest); return (EPKG_OK); }
struct pkg_repo_it * pkg_repo_binary_shlib_require(struct pkg_repo *repo, const char *provide) { sqlite3_stmt *stmt; sqlite3 *sqlite = PRIV_GET(repo); struct sbuf *sql = NULL; int ret; const char basesql[] = "" "SELECT p.id, p.origin, p.name, p.version, p.comment, " "p.name as uniqueid, " "p.prefix, p.desc, p.arch, p.maintainer, p.www, " "p.licenselogic, p.flatsize, p.pkgsize, " "p.cksum, p.manifestdigest, p.path AS repopath, '%s' AS dbname " "FROM packages AS p INNER JOIN pkg_shlibs_required AS ps ON " "p.id = ps.package_id " "WHERE ps.shlib_id = (SELECT id FROM shlibs WHERE name=?1);"; sql = sbuf_new_auto(); sbuf_printf(sql, basesql, repo->name); sbuf_finish(sql); pkg_debug(4, "Pkgdb: running '%s'", sbuf_data(sql)); ret = sqlite3_prepare_v2(sqlite, sbuf_data(sql), -1, &stmt, NULL); if (ret != SQLITE_OK) { ERROR_SQLITE(sqlite, sbuf_data(sql)); sbuf_delete(sql); return (NULL); } sbuf_delete(sql); pkg_debug(1, "> loading provides"); sqlite3_bind_text(stmt, 1, provide, -1, SQLITE_TRANSIENT); return (pkg_repo_binary_it_new(repo, stmt, PKGDB_IT_FLAG_ONCE)); }
struct sbuf * exec_buf(const char *cmd) { FILE *fp; char buf[BUFSIZ]; struct sbuf *res; if ((fp = popen(cmd, "r")) == NULL) return (NULL); res = sbuf_new_auto(); while (fgets(buf, BUFSIZ, fp) != NULL) sbuf_cat(res, buf); pclose(fp); if (sbuf_len(res) == 0) { sbuf_delete(res); return (NULL); } sbuf_finish(res); return (res); }
bool ucl_object_emit_sbuf(const ucl_object_t *obj, enum ucl_emitter emit_type, struct sbuf **buf) { bool ret = false; struct ucl_emitter_functions func = { .ucl_emitter_append_character = ucl_sbuf_append_character, .ucl_emitter_append_len = ucl_sbuf_append_len, .ucl_emitter_append_int = ucl_sbuf_append_int, .ucl_emitter_append_double = ucl_sbuf_append_double }; if (*buf == NULL) *buf = sbuf_new_auto(); else sbuf_clear(*buf); func.ud = *buf; ret = ucl_object_emit_full(obj, emit_type, &func); sbuf_finish(*buf); return (ret); }
static void subst_packagesite(const char *abi) { struct sbuf *newval; const char *variable_string; const char *oldval; if (c[PACKAGESITE].value != NULL) oldval = c[PACKAGESITE].value; else oldval = c[PACKAGESITE].val; if ((variable_string = strstr(oldval, "${ABI}")) == NULL) return; newval = sbuf_new_auto(); sbuf_bcat(newval, oldval, variable_string - oldval); sbuf_cat(newval, abi); sbuf_cat(newval, variable_string + strlen("${ABI}")); sbuf_finish(newval); free(c[PACKAGESITE].value); c[PACKAGESITE].value = strdup(sbuf_data(newval)); }
/* mtree_resolve() sets errno to indicate why NULL was returned. */ static char * mtree_resolve(const char *spec, int *istemp) { struct sbuf *sb; char *res, *var; const char *base, *p, *v; size_t len; int c, error, quoted, subst; len = strlen(spec); if (len == 0) { errno = EINVAL; return (NULL); } c = (len > 1) ? (spec[0] == spec[len - 1]) ? spec[0] : 0 : 0; *istemp = (c == '`') ? 1 : 0; subst = (c == '`' || c == '"') ? 1 : 0; quoted = (subst || c == '\'') ? 1 : 0; if (!subst) { res = strdup(spec + quoted); if (res != NULL && quoted) res[len - 2] = '\0'; return (res); } sb = sbuf_new_auto(); if (sb == NULL) { errno = ENOMEM; return (NULL); } base = spec + 1; len -= 2; error = 0; while (len > 0) { p = strchr(base, '$'); if (p == NULL) { sbuf_bcat(sb, base, len); base += len; len = 0; continue; } /* The following is safe. spec always starts with a quote. */ if (p[-1] == '\\') p--; if (base != p) { sbuf_bcat(sb, base, p - base); len -= p - base; base = p; } if (*p == '\\') { sbuf_putc(sb, '$'); base += 2; len -= 2; continue; } /* Skip the '$'. */ base++; len--; /* Handle ${X} vs $X. */ v = base; if (*base == '{') { p = strchr(v, '}'); if (p == NULL) p = v; } else p = v; len -= (p + 1) - base; base = p + 1; if (v == p) { sbuf_putc(sb, *v); continue; } error = ENOMEM; var = calloc(p - v, 1); if (var == NULL) break; memcpy(var, v + 1, p - v - 1); if (strcmp(var, ".CURDIR") == 0) { res = getcwd(NULL, 0); if (res == NULL) break; } else if (strcmp(var, ".PROG") == 0) { res = strdup(getprogname()); if (res == NULL) break; } else { v = getenv(var); if (v != NULL) { res = strdup(v); if (res == NULL) break; } else res = NULL; } error = 0; if (res != NULL) { sbuf_cat(sb, res); free(res); } free(var); } sbuf_finish(sb); res = (error == 0) ? strdup(sbuf_data(sb)) : NULL; sbuf_delete(sb); if (res == NULL) errno = ENOMEM; return (res); }
static int pkg_create_from_dir(struct pkg *pkg, const char *root, struct packing *pkg_archive) { char fpath[MAXPATHLEN]; struct pkg_file *file = NULL; struct pkg_dir *dir = NULL; char *m; int ret; const char *mtree; bool developer; struct stat st; char sha256[SHA256_DIGEST_LENGTH * 2 + 1]; int64_t flatsize = 0; ucl_object_t *obj; if (pkg_is_valid(pkg) != EPKG_OK) { pkg_emit_error("the package is not valid"); return (EPKG_FATAL); } obj = pkg_annotation_lookup(pkg, "relocated"); /* * Get / compute size / checksum if not provided in the manifest */ while (pkg_files(pkg, &file) == EPKG_OK) { const char *pkg_path = pkg_file_path(file); const char *pkg_sum = pkg_file_cksum(file); snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "", obj ? pkg_object_string(obj) : "", pkg_path); if (lstat(fpath, &st) != 0 || S_ISLNK(st.st_mode)) continue; if (file->size == 0) file->size = (int64_t)st.st_size; flatsize += file->size; if (pkg_sum == NULL || pkg_sum[0] == '\0') { if (pkg->type == PKG_OLD_FILE) { if (md5_file(fpath, sha256) != EPKG_OK) return (EPKG_FATAL); } else { if (sha256_file(fpath, sha256) != EPKG_OK) return (EPKG_FATAL); } strlcpy(file->sum, sha256, sizeof(file->sum)); } } pkg_set(pkg, PKG_FLATSIZE, flatsize); if (pkg->type == PKG_OLD_FILE) { const char *desc, *display, *comment; char oldcomment[BUFSIZ]; pkg_old_emit_content(pkg, &m); packing_append_buffer(pkg_archive, m, "+CONTENTS", strlen(m)); free(m); pkg_get(pkg, PKG_DESC, &desc, PKG_MESSAGE, &display, PKG_COMMENT, &comment); packing_append_buffer(pkg_archive, desc, "+DESC", strlen(desc)); packing_append_buffer(pkg_archive, display, "+DISPLAY", strlen(display)); snprintf(oldcomment, sizeof(oldcomment), "%s\n", comment); packing_append_buffer(pkg_archive, oldcomment, "+COMMENT", strlen(oldcomment)); } else { /* * Register shared libraries used by the package if * SHLIBS enabled in conf. Deletes shlib info if not. */ struct sbuf *b = sbuf_new_auto(); pkg_register_shlibs(pkg, root); pkg_emit_manifest_sbuf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, NULL); packing_append_buffer(pkg_archive, sbuf_data(b), "+COMPACT_MANIFEST", sbuf_len(b)); sbuf_clear(b); pkg_emit_manifest_sbuf(pkg, b, 0, NULL); sbuf_finish(b); packing_append_buffer(pkg_archive, sbuf_data(b), "+MANIFEST", sbuf_len(b)); sbuf_delete(b); } pkg_get(pkg, PKG_MTREE, &mtree); if (mtree != NULL) packing_append_buffer(pkg_archive, mtree, "+MTREE_DIRS", strlen(mtree)); while (pkg_files(pkg, &file) == EPKG_OK) { const char *pkg_path = pkg_file_path(file); snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "", obj ? pkg_object_string(obj) : "", pkg_path); ret = packing_append_file_attr(pkg_archive, fpath, pkg_path, file->uname, file->gname, file->perm); developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE")); if (developer && ret != EPKG_OK) return (ret); } while (pkg_dirs(pkg, &dir) == EPKG_OK) { const char *pkg_path = pkg_dir_path(dir); snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "", obj ? pkg_object_string(obj) : "", pkg_path); ret = packing_append_file_attr(pkg_archive, fpath, pkg_path, dir->uname, dir->gname, dir->perm); developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE")); if (developer && ret != EPKG_OK) return (ret); } return (EPKG_OK); }
int format_exec_cmd(char **dest, const char *in, const char *prefix, const char *plist_file, char *line) { struct sbuf *buf = sbuf_new_auto(); char path[MAXPATHLEN + 1]; char *cp; while (in[0] != '\0') { if (in[0] == '%') { in++; switch(in[0]) { case 'D': sbuf_cat(buf, prefix); break; case 'F': if (plist_file == NULL) { pkg_emit_error("No files defined %%F couldn't be expanded, ignoring %s", in); sbuf_finish(buf); sbuf_free(buf); return (EPKG_FATAL); } sbuf_cat(buf, plist_file); break; case 'f': if (plist_file == NULL) { pkg_emit_error("No files defined %%f couldn't be expanded, ignoring %s", in); sbuf_finish(buf); sbuf_free(buf); return (EPKG_FATAL); } if (prefix[strlen(prefix) - 1] == '/') snprintf(path, sizeof(path), "%s%s", prefix, plist_file); else snprintf(path, sizeof(path), "%s/%s", prefix, plist_file); cp = strrchr(path, '/'); cp ++; sbuf_cat(buf, cp); break; case 'B': if (plist_file == NULL) { pkg_emit_error("No files defined %%B couldn't be expanded, ignoring %s", in); sbuf_finish(buf); sbuf_free(buf); return (EPKG_FATAL); } if (prefix[strlen(prefix) - 1] == '/') snprintf(path, sizeof(path), "%s%s", prefix, plist_file); else snprintf(path, sizeof(path), "%s/%s", prefix, plist_file); cp = strrchr(path, '/'); cp[0] = '\0'; sbuf_cat(buf, path); break; case '%': sbuf_putc(buf, '%'); break; case '@': if (line != NULL) { sbuf_cat(buf, line); break; } /* * no break here because if line is not * given (default exec) %@ does not * exists */ default: sbuf_putc(buf, '%'); sbuf_putc(buf, in[0]); break; } } else { sbuf_putc(buf, in[0]); } in++; } sbuf_finish(buf); *dest = strdup(sbuf_data(buf)); sbuf_free(buf); return (EPKG_OK); }
static void print_query(struct pkg *pkg, char *qstr, char multiline) { struct sbuf *output = sbuf_new_auto(); struct pkg_dep *dep = NULL; struct pkg_category *cat = NULL; struct pkg_option *option = NULL; struct pkg_file *file = NULL; struct pkg_dir *dir = NULL; struct pkg_license *lic = NULL; struct pkg_user *user = NULL; struct pkg_group *group = NULL; struct pkg_script *scripts = NULL; switch (multiline) { case 'd': while (pkg_deps(pkg, &dep) == EPKG_OK) { format_str(pkg, output, qstr, dep); printf("%s\n", sbuf_get(output)); break; } case 'r': while (pkg_rdeps(pkg, &dep) == EPKG_OK) { format_str(pkg, output, qstr, dep); printf("%s\n", sbuf_get(output)); } break; case 'C': while (pkg_categories(pkg, &cat) == EPKG_OK) { format_str(pkg, output, qstr, cat); printf("%s\n", sbuf_get(output)); } break; case 'O': while (pkg_options(pkg, &option) == EPKG_OK) { format_str(pkg, output, qstr, option); printf("%s\n", sbuf_get(output)); } break; case 'F': while (pkg_files(pkg, &file) == EPKG_OK) { format_str(pkg, output, qstr, file); printf("%s\n", sbuf_get(output)); } break; case 'D': while (pkg_dirs(pkg, &dir) == EPKG_OK) { format_str(pkg, output, qstr, dir); printf("%s\n", sbuf_get(output)); } break; case 'L': while (pkg_licenses(pkg, &lic) == EPKG_OK) { format_str(pkg, output, qstr, lic); printf("%s\n", sbuf_get(output)); } break; case 'U': while (pkg_users(pkg, &user) == EPKG_OK) { format_str(pkg, output, qstr, user); printf("%s\n", sbuf_get(output)); } break; case 'G': while (pkg_users(pkg, &user) == EPKG_OK) { format_str(pkg, output, qstr, group); printf("%s\n", sbuf_get(output)); } break; case 'S': while (pkg_scripts(pkg, &scripts) == EPKG_OK) { format_str(pkg, output, qstr, scripts); printf("%s\n", sbuf_get(output)); } break; default: format_str(pkg, output, qstr, dep); printf("%s\n", sbuf_get(output)); break; } sbuf_delete(output); }
struct pkgdb_it * pkgdb_rquery(struct pkgdb *db, const char *pattern, match_t match, const char *repo) { sqlite3_stmt *stmt = NULL; struct sbuf *sql = NULL; const char *reponame = NULL; const char *comp = NULL; int ret; char basesql[BUFSIZ] = "" "SELECT id, origin, name, version, comment, " "prefix, desc, arch, maintainer, www, " "licenselogic, flatsize, pkgsize, " "cksum, manifestdigest, path AS repopath, '%1$s' AS dbname " "FROM '%1$s'.packages p"; assert(db != NULL); assert(match == MATCH_ALL || (pattern != NULL && pattern[0] != '\0')); /* * If we have no remote repos loaded, we just return nothing instead of failing * an assert deep inside pkgdb_get_reponame */ if (db->type != PKGDB_REMOTE) return (NULL); reponame = pkgdb_get_reponame(db, repo); sql = sbuf_new_auto(); comp = pkgdb_get_pattern_query(pattern, match); if (comp && comp[0]) strlcat(basesql, comp, sizeof(basesql)); /* * Working on multiple remote repositories */ if (reponame == NULL) { /* duplicate the query via UNION for all the attached * databases */ ret = pkgdb_sql_all_attached(db->sqlite, sql, basesql, " UNION ALL "); if (ret != EPKG_OK) { sbuf_delete(sql); return (NULL); } } else sbuf_printf(sql, basesql, reponame, reponame); sbuf_cat(sql, " ORDER BY name;"); sbuf_finish(sql); pkg_debug(4, "Pkgdb: running '%s'", sbuf_get(sql)); ret = sqlite3_prepare_v2(db->sqlite, sbuf_get(sql), sbuf_size(sql), &stmt, NULL); if (ret != SQLITE_OK) { ERROR_SQLITE(db->sqlite); sbuf_delete(sql); return (NULL); } sbuf_delete(sql); if (match != MATCH_ALL && match != MATCH_CONDITION) sqlite3_bind_text(stmt, 1, pattern, -1, SQLITE_TRANSIENT); return (pkgdb_it_new(db, stmt, PKG_REMOTE, PKGDB_IT_FLAG_ONCE)); }
int write_userconfig(char const * file) { int fd; int i, j; struct sbuf *buf; FILE *fp; if (file == NULL) file = _PATH_PW_CONF; if ((fd = open(file, O_CREAT|O_RDWR|O_TRUNC|O_EXLOCK, 0644)) == -1) return (0); if ((fp = fdopen(fd, "w")) == NULL) { close(fd); return (0); } buf = sbuf_new_auto(); for (i = _UC_NONE; i < _UC_FIELDS; i++) { int quote = 1; sbuf_clear(buf); switch (i) { case _UC_DEFAULTPWD: sbuf_cat(buf, boolean_str(config.default_password)); break; case _UC_REUSEUID: sbuf_cat(buf, boolean_str(config.reuse_uids)); break; case _UC_REUSEGID: sbuf_cat(buf, boolean_str(config.reuse_gids)); break; case _UC_NISPASSWD: sbuf_cat(buf, config.nispasswd ? config.nispasswd : ""); quote = 0; break; case _UC_DOTDIR: sbuf_cat(buf, config.dotdir ? config.dotdir : boolean_str(0)); break; case _UC_NEWMAIL: sbuf_cat(buf, config.newmail ? config.newmail : boolean_str(0)); break; case _UC_LOGFILE: sbuf_cat(buf, config.logfile ? config.logfile : boolean_str(0)); break; case _UC_HOMEROOT: sbuf_cat(buf, config.home); break; case _UC_HOMEMODE: sbuf_printf(buf, "%04o", config.homemode); quote = 0; break; case _UC_SHELLPATH: sbuf_cat(buf, config.shelldir); break; case _UC_SHELLS: for (j = 0; j < _UC_MAXSHELLS && system_shells[j] != NULL; j++) sbuf_printf(buf, "%s\"%s\"", j ? "," : "", system_shells[j]); quote = 0; break; case _UC_DEFAULTSHELL: sbuf_cat(buf, config.shell_default ? config.shell_default : bourne_shell); break; case _UC_DEFAULTGROUP: sbuf_cat(buf, config.default_group ? config.default_group : ""); break; case _UC_EXTRAGROUPS: for (j = 0; config.groups != NULL && j < (int)config.groups->sl_cur; j++) sbuf_printf(buf, "%s\"%s\"", j ? "," : "", config.groups->sl_str[j]); quote = 0; break; case _UC_DEFAULTCLASS: sbuf_cat(buf, config.default_class ? config.default_class : ""); break; case _UC_MINUID: sbuf_printf(buf, "%u", config.min_uid); quote = 0; break; case _UC_MAXUID: sbuf_printf(buf, "%u", config.max_uid); quote = 0; break; case _UC_MINGID: sbuf_printf(buf, "%u", config.min_gid); quote = 0; break; case _UC_MAXGID: sbuf_printf(buf, "%u", config.max_gid); quote = 0; break; case _UC_EXPIRE: sbuf_printf(buf, "%d", config.expire_days); quote = 0; break; case _UC_PASSWORD: sbuf_printf(buf, "%d", config.password_days); quote = 0; break; case _UC_NONE: break; } sbuf_finish(buf); if (comments[i]) fputs(comments[i], fp); if (*kwds[i]) { if (quote) fprintf(fp, "%s = \"%s\"\n", kwds[i], sbuf_data(buf)); else fprintf(fp, "%s = %s\n", kwds[i], sbuf_data(buf)); #if debugging printf("WROTE: %s = %s\n", kwds[i], sbuf_data(buf)); #endif } } sbuf_delete(buf); return (fclose(fp) != EOF); }
static int do_extract(struct archive *a, struct archive_entry *ae, const char *location, int nfiles, struct pkg *pkg, struct pkg *local) { int retcode = EPKG_OK; int ret = 0, cur_file = 0; char path[MAXPATHLEN], pathname[MAXPATHLEN], rpath[MAXPATHLEN]; struct stat st; const struct stat *aest; bool renamed = false; const struct pkg_file *rf; struct pkg_config_file *rcf; struct sbuf *newconf; bool automerge = pkg_object_bool(pkg_config_get("AUTOMERGE")); unsigned long set, clear; #ifndef HAVE_ARC4RANDOM srand(time(NULL)); #endif if (nfiles == 0) return (EPKG_OK); pkg_emit_extract_begin(pkg); pkg_emit_progress_start(NULL); newconf = sbuf_new_auto(); do { ret = ARCHIVE_OK; sbuf_clear(newconf); rf = NULL; rcf = NULL; pkg_absolutepath(archive_entry_pathname(ae), path, sizeof(path)); snprintf(pathname, sizeof(pathname), "%s%s%s", location ? location : "", *path == '/' ? "" : "/", path ); strlcpy(rpath, pathname, sizeof(rpath)); aest = archive_entry_stat(ae); archive_entry_fflags(ae, &set, &clear); if (lstat(rpath, &st) != -1) { /* * We have an existing file on the path, so handle it */ if (!S_ISDIR(aest->st_mode)) { pkg_debug(2, "Old version found, renaming"); pkg_add_file_random_suffix(rpath, sizeof(rpath), 12); renamed = true; } if (!S_ISDIR(st.st_mode) && S_ISDIR(aest->st_mode)) { if (S_ISLNK(st.st_mode)) { if (stat(rpath, &st) == -1) { pkg_emit_error("Dead symlink %s", rpath); } else { pkg_debug(2, "Directory is a symlink, use it"); pkg_emit_progress_tick(cur_file++, nfiles); continue; } } } } archive_entry_set_pathname(ae, rpath); /* load in memory the content of config files */ if (pkg_is_config_file(pkg, path, &rf, &rcf)) { pkg_debug(1, "Populating config_file %s", pathname); size_t len = archive_entry_size(ae); rcf->content = malloc(len); archive_read_data(a, rcf->content, len); if (renamed && (!automerge || local == NULL)) strlcat(pathname, ".pkgnew", sizeof(pathname)); } /* * check if the file is already provided by previous package */ if (!automerge) attempt_to_merge(renamed, rcf, local, pathname, path, newconf); if (sbuf_len(newconf) == 0 && (rcf == NULL || rcf->content == NULL)) { pkg_debug(1, "Extracting: %s", archive_entry_pathname(ae)); int install_as_user = (getenv("INSTALL_AS_USER") != NULL); int extract_flags = EXTRACT_ARCHIVE_FLAGS; if (install_as_user) { /* when installing as user don't try to set file ownership */ extract_flags &= ~ARCHIVE_EXTRACT_OWNER; } ret = archive_read_extract(a, ae, extract_flags); } else { if (sbuf_len(newconf) == 0) { sbuf_cat(newconf, rcf->content); sbuf_finish(newconf); } pkg_debug(2, "Writing conf in %s", pathname); unlink(rpath); FILE *f = fopen(rpath, "w+"); fprintf(f, "%s", sbuf_data(newconf)); fclose(f); } if (ret != ARCHIVE_OK) { /* * show error except when the failure is during * extracting a directory and that the directory already * exists. * this allow to install packages linux_base from * package for example */ if (archive_entry_filetype(ae) != AE_IFDIR || !is_dir(pathname)) { pkg_emit_error("archive_read_extract(): %s", archive_error_string(a)); retcode = EPKG_FATAL; goto cleanup; } } /* Reapply modes to the directories to work around a problem on FreeBSD 9 */ if (archive_entry_filetype(ae) == AE_IFDIR) chmod(pathname, aest->st_mode); pkg_emit_progress_tick(cur_file++, nfiles); /* Rename old file */ if (renamed) { pkg_debug(1, "Renaming %s -> %s", rpath, pathname); #ifdef HAVE_CHFLAGS bool old = false; if (set & NOCHANGESFLAGS) chflags(rpath, 0); if (lstat(pathname, &st) != -1) { old = true; if (st.st_flags & NOCHANGESFLAGS) chflags(pathname, 0); } #endif if (rename(rpath, pathname) == -1) { #ifdef HAVE_CHFLAGS /* restore flags */ if (old) chflags(pathname, st.st_flags); #endif pkg_emit_error("cannot rename %s to %s: %s", rpath, pathname, strerror(errno)); retcode = EPKG_FATAL; goto cleanup; } #ifdef HAVE_CHFLAGS /* Restore flags */ chflags(pathname, set); #endif } if (string_end_with(pathname, ".pkgnew")) pkg_emit_notice("New configuration file: %s", pathname); renamed = false; } while ((ret = archive_read_next_header(a, &ae)) == ARCHIVE_OK); if (ret != ARCHIVE_EOF) { pkg_emit_error("archive_read_next_header(): %s", archive_error_string(a)); retcode = EPKG_FATAL; } cleanup: pkg_emit_progress_tick(nfiles, nfiles); pkg_emit_extract_finished(pkg); if (renamed && retcode == EPKG_FATAL) { #ifdef HAVE_CHFLAGS if (set & NOCHANGESFLAGS) chflags(rpath, set & ~NOCHANGESFLAGS); #endif unlink(rpath); } return (retcode); }