/* * Print SMP error output. For userland commands, we need the cam_device * structure so we can get the path information from the CCB. */ #ifdef _KERNEL void smp_error_sbuf(struct ccb_smpio *smpio, struct sbuf *sb) #else /* !_KERNEL*/ void smp_error_sbuf(struct cam_device *device, struct ccb_smpio *smpio, struct sbuf *sb) #endif /* _KERNEL/!_KERNEL */ { char path_str[64]; #ifdef _KERNEL xpt_path_string(smpio->ccb_h.path, path_str, sizeof(path_str)); #else cam_path_string(device, path_str, sizeof(path_str)); #endif smp_command_sbuf(smpio, sb, path_str, 80 - strlen(path_str), 80); sbuf_printf(sb, "\n"); sbuf_cat(sb, path_str); sbuf_printf(sb, "SMP Error: %s (0x%x)\n", smp_error_desc(smpio->smp_response[2]), smpio->smp_response[2]); }
/* * Print a number of attribute values */ void pr_any_att_vals( const ncatt_t *ap, /* attribute */ const void *vals /* pointer to block of values */ ) { size_t iel; size_t len = ap->len; /* number of values to print */ const char *valp = (const char *)vals; safebuf_t *sb = sbuf_new(); for (iel = 0; iel < len - 1; iel++) { print_any_att_val(sb, ap, (void *)valp); valp += ap->tinfo->size; /* next value according to type */ sbuf_cat(sb, iel == len - 1 ? "" : ", "); lput(sbuf_str(sb)); } print_any_att_val(sb, ap, (void *)valp); lput(sbuf_str(sb)); sbuf_free(sb); }
/* * Print a number of variable values, where the optional comments * for each value identify the variable, and each dimension index. */ static void pr_any_vals( const ncvar_t *vp, /* variable */ size_t len, /* number of values to print */ boolean more, /* true if more data for this row will * follow, so add trailing comma */ boolean lastrow, /* true if this is the last row for this * variable, so terminate with ";" instead * of "," */ const void *vals, /* pointer to block of values */ const fspec_t* fsp, /* formatting specs */ const size_t *cor /* corner coordinates */ ) { long iel; safebuf_t *sb = sbuf_new(); const char *valp = (const char *)vals; for (iel = 0; iel < len-1; iel++) { print_any_val(sb, vp, (void *)valp); valp += vp->tinfo->size; /* next value according to type */ if (fsp->full_data_cmnts) { printf("%s, ", sb->buf); annotate (vp, fsp, cor, iel); } else { sbuf_cat(sb, ", "); lput(sbuf_str(sb)); } } print_any_val(sb, vp, (void *)valp); if (fsp->full_data_cmnts) { printf("%s", sbuf_str(sb)); lastdelim (more, lastrow); annotate (vp, fsp, cor, iel); } else { lput(sbuf_str(sb)); lastdelim2 (more, lastrow); } sbuf_free(sb); }
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); }
static void pipeevent(struct pkg_event *ev) { int i; struct pkg_dep *dep = NULL; struct sbuf *msg, *buf; struct pkg_event_conflict *cur_conflict; if (eventpipe < 0) return; msg = sbuf_new_auto(); buf = sbuf_new_auto(); switch(ev->type) { case PKG_EVENT_ERRNO: sbuf_printf(msg, "{ \"type\": \"ERROR\", " "\"data\": {" "\"msg\": \"%s(%s): %s\"," "\"errno\": %d}}", sbuf_json_escape(buf, ev->e_errno.func), sbuf_json_escape(buf, ev->e_errno.arg), sbuf_json_escape(buf, strerror(ev->e_errno.no)), ev->e_errno.no); break; case PKG_EVENT_ERROR: sbuf_printf(msg, "{ \"type\": \"ERROR\", " "\"data\": {\"msg\": \"%s\"}}", sbuf_json_escape(buf, ev->e_pkg_error.msg)); break; case PKG_EVENT_NOTICE: sbuf_printf(msg, "{ \"type\": \"NOTICE\", " "\"data\": {\"msg\": \"%s\"}}", sbuf_json_escape(buf, ev->e_pkg_notice.msg)); break; case PKG_EVENT_DEVELOPER_MODE: sbuf_printf(msg, "{ \"type\": \"ERROR\", " "\"data\": {\"msg\": \"DEVELOPER_MODE: %s\"}}", sbuf_json_escape(buf, ev->e_pkg_error.msg)); break; case PKG_EVENT_UPDATE_ADD: sbuf_printf(msg, "{ \"type\": \"INFO_UPDATE_ADD\", " "\"data\": { " "\"fetched\": %d, " "\"total\": %d" "}}", ev->e_upd_add.done, ev->e_upd_add.total ); break; case PKG_EVENT_UPDATE_REMOVE: sbuf_printf(msg, "{ \"type\": \"INFO_UPDATE_REMOVE\", " "\"data\": { " "\"fetched\": %d, " "\"total\": %d" "}}", ev->e_upd_remove.done, ev->e_upd_remove.total ); break; case PKG_EVENT_FETCH_BEGIN: sbuf_printf(msg, "{ \"type\": \"INFO_FETCH_BEGIN\", " "\"data\": { " "\"url\": \"%s\" " "}}", sbuf_json_escape(buf, ev->e_fetching.url) ); break; case PKG_EVENT_FETCH_FINISHED: sbuf_printf(msg, "{ \"type\": \"INFO_FETCH_FINISHED\", " "\"data\": { " "\"url\": \"%s\" " "}}", sbuf_json_escape(buf, ev->e_fetching.url) ); break; case PKG_EVENT_INSTALL_BEGIN: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_BEGIN\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\"" "}}", ev->e_install_begin.pkg, ev->e_install_begin.pkg); break; case PKG_EVENT_EXTRACT_BEGIN: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_EXTRACT_BEGIN\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\"" "}}", ev->e_extract_begin.pkg, ev->e_extract_begin.pkg); break; case PKG_EVENT_EXTRACT_FINISHED: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_EXTRACT_FINISHED\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\"" "}}", ev->e_extract_finished.pkg, ev->e_extract_finished.pkg); break; case PKG_EVENT_INSTALL_FINISHED: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_FINISHED\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\", " "\"message\": \"%S\"" "}}", ev->e_install_finished.pkg, ev->e_install_finished.pkg, ev->e_install_finished.pkg->message ? sbuf_json_escape(buf, ev->e_install_finished.pkg->message->str) : ""); break; case PKG_EVENT_INTEGRITYCHECK_BEGIN: sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_BEGIN\", " "\"data\": {}}"); break; case PKG_EVENT_INTEGRITYCHECK_CONFLICT: sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_CONFLICT\"," "\"data\": { " "\"pkguid\": \"%s\", " "\"pkgpath\": \"%s\", " "\"conflicts\": [", ev->e_integrity_conflict.pkg_uid, ev->e_integrity_conflict.pkg_path); cur_conflict = ev->e_integrity_conflict.conflicts; while (cur_conflict != NULL) { if (cur_conflict->next != NULL) { sbuf_printf(msg, "{\"uid\":\"%s\"},", cur_conflict->uid); } else { sbuf_printf(msg, "{\"uid\":\"%s\"}", cur_conflict->uid); break; } cur_conflict = cur_conflict->next; } sbuf_cat(msg, "]}}"); break; case PKG_EVENT_INTEGRITYCHECK_FINISHED: sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_FINISHED\", " "\"data\": {\"conflicting\": %d}}", ev->e_integrity_finished.conflicting); break; case PKG_EVENT_DEINSTALL_BEGIN: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_BEGIN\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\"" "}}", ev->e_deinstall_begin.pkg, ev->e_deinstall_begin.pkg); break; case PKG_EVENT_DEINSTALL_FINISHED: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_FINISHED\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\"" "}}", ev->e_deinstall_finished.pkg, ev->e_deinstall_finished.pkg); break; case PKG_EVENT_UPGRADE_BEGIN: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_BEGIN\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\" ," "\"pkgnewversion\": \"%v\"" "}}", ev->e_upgrade_begin.o, ev->e_upgrade_begin.o, ev->e_upgrade_begin.n); break; case PKG_EVENT_UPGRADE_FINISHED: pkg_sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_FINISHED\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\" ," "\"pkgnewversion\": \"%v\"" "}}", ev->e_upgrade_finished.o, ev->e_upgrade_finished.o, ev->e_upgrade_finished.n); break; case PKG_EVENT_LOCKED: pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_LOCKED\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%n\"" "}}", ev->e_locked.pkg, ev->e_locked.pkg); break; case PKG_EVENT_REQUIRED: pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_REQUIRED\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\", " "\"force\": %S, " "\"required_by\": [", ev->e_required.pkg, ev->e_required.pkg, ev->e_required.force == 1 ? "true": "false"); while (pkg_rdeps(ev->e_required.pkg, &dep) == EPKG_OK) sbuf_printf(msg, "{ \"pkgname\": \"%s\", " "\"pkgversion\": \"%s\" }, ", dep->name, dep->version); sbuf_setpos(msg, sbuf_len(msg) - 2); sbuf_cat(msg, "]}}"); break; case PKG_EVENT_ALREADY_INSTALLED: pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_ALREADY_INSTALLED\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\"" "}}", ev->e_already_installed.pkg, ev->e_already_installed.pkg); break; case PKG_EVENT_MISSING_DEP: sbuf_printf(msg, "{ \"type\": \"ERROR_MISSING_DEP\", " "\"data\": { " "\"depname\": \"%s\", " "\"depversion\": \"%s\"" "}}" , ev->e_missing_dep.dep->name, ev->e_missing_dep.dep->version); break; case PKG_EVENT_NOREMOTEDB: sbuf_printf(msg, "{ \"type\": \"ERROR_NOREMOTEDB\", " "\"data\": { " "\"url\": \"%s\" " "}}" , ev->e_remotedb.repo); break; case PKG_EVENT_NOLOCALDB: sbuf_printf(msg, "{ \"type\": \"ERROR_NOLOCALDB\", " "\"data\": {} "); break; case PKG_EVENT_NEWPKGVERSION: sbuf_printf(msg, "{ \"type\": \"INFO_NEWPKGVERSION\", " "\"data\": {} "); break; case PKG_EVENT_FILE_MISMATCH: pkg_sbuf_printf(msg, "{ \"type\": \"ERROR_FILE_MISMATCH\", " "\"data\": { " "\"pkgname\": \"%n\", " "\"pkgversion\": \"%v\", " "\"path\": \"%S\"" "}}", ev->e_file_mismatch.pkg, ev->e_file_mismatch.pkg, sbuf_json_escape(buf, ev->e_file_mismatch.file->path)); break; case PKG_EVENT_PLUGIN_ERRNO: sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", " "\"data\": {" "\"plugin\": \"%s\", " "\"msg\": \"%s(%s): %s\"," "\"errno\": %d" "}}", pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME), sbuf_json_escape(buf, ev->e_plugin_errno.func), sbuf_json_escape(buf, ev->e_plugin_errno.arg), sbuf_json_escape(buf, strerror(ev->e_plugin_errno.no)), ev->e_plugin_errno.no); break; case PKG_EVENT_PLUGIN_ERROR: sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", " "\"data\": {" "\"plugin\": \"%s\", " "\"msg\": \"%s\"" "}}", pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME), sbuf_json_escape(buf, ev->e_plugin_error.msg)); break; case PKG_EVENT_PLUGIN_INFO: sbuf_printf(msg, "{ \"type\": \"INFO_PLUGIN\", " "\"data\": {" "\"plugin\": \"%s\", " "\"msg\": \"%s\"" "}}", pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME), sbuf_json_escape(buf, ev->e_plugin_info.msg)); break; case PKG_EVENT_INCREMENTAL_UPDATE: sbuf_printf(msg, "{ \"type\": \"INFO_INCREMENTAL_UPDATE\", " "\"data\": {" "\"name\": \"%s\", " "\"processed\": %d" "}}", ev->e_incremental_update.reponame, ev->e_incremental_update.processed); break; case PKG_EVENT_QUERY_YESNO: sbuf_printf(msg, "{ \"type\": \"QUERY_YESNO\", " "\"data\": {" "\"msg\": \"%s\"," "\"default\": \"%d\"" "}}", ev->e_query_yesno.msg, ev->e_query_yesno.deft); break; case PKG_EVENT_QUERY_SELECT: sbuf_printf(msg, "{ \"type\": \"QUERY_SELECT\", " "\"data\": {" "\"msg\": \"%s\"," "\"ncnt\": \"%d\"," "\"default\": \"%d\"," "\"items\": [" , ev->e_query_select.msg, ev->e_query_select.ncnt, ev->e_query_select.deft); for (i = 0; i < ev->e_query_select.ncnt - 1; i++) { sbuf_printf(msg, "{ \"text\": \"%s\" },", ev->e_query_select.items[i]); } sbuf_printf(msg, "{ \"text\": \"%s\" } ] }}", ev->e_query_select.items[i]); break; case PKG_EVENT_PROGRESS_START: sbuf_printf(msg, "{ \"type\": \"INFO_PROGRESS_START\", " "\"data\": {}}"); break; case PKG_EVENT_PROGRESS_TICK: sbuf_printf(msg, "{ \"type\": \"INFO_PROGRESS_TICK\", " "\"data\": { \"current\": %ld, \"total\" : %ld}}", ev->e_progress_tick.current, ev->e_progress_tick.total); break; case PKG_EVENT_BACKUP: case PKG_EVENT_RESTORE: break; default: break; } sbuf_finish(msg); dprintf(eventpipe, "%s\n", sbuf_data(msg)); sbuf_delete(msg); sbuf_delete(buf); }
int exec_add(int argc, char **argv) { struct pkgdb *db = NULL; struct sbuf *failedpkgs = NULL; 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); } failedpkgs = sbuf_new_auto(); 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, 0)) != EPKG_OK) break; file = path; } else { file = argv[i]; if (access(file, F_OK) != 0) { warn("%s",file); if (errno == ENOENT) warnx("Did you mean 'pkg install %s'?", file); sbuf_cat(failedpkgs, argv[i]); if (i != argc - 1) sbuf_printf(failedpkgs, ", "); failedpkgcount++; continue; } } pkg_open(&p, file); 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("\nFailed to install the following %d package(s): %s\n", failedpkgcount, sbuf_data(failedpkgs)); } sbuf_delete(failedpkgs); if (messages != NULL) { sbuf_finish(messages); printf("%s", sbuf_data(messages)); } return (retcode == EPKG_OK ? EX_OK : EX_SOFTWARE); }
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)); }
static void format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, void *data) { char size[7]; const char *tmp; bool automatic; int64_t flatsize; lic_t licenselogic; sbuf_clear(dest); while (qstr[0] != '\0') { if (qstr[0] == '%') { qstr++; switch (qstr[0]) { case 'n': pkg_get(pkg, PKG_NAME, &tmp); sbuf_cat(dest, tmp); break; case 'v': pkg_get(pkg, PKG_VERSION, &tmp); sbuf_cat(dest, tmp); break; case 'o': pkg_get(pkg, PKG_ORIGIN, &tmp); sbuf_cat(dest, tmp); break; case 'p': pkg_get(pkg, PKG_PREFIX, &tmp); sbuf_cat(dest, tmp); break; case 'm': pkg_get(pkg, PKG_MAINTAINER, &tmp); sbuf_cat(dest, tmp); break; case 'c': pkg_get(pkg, PKG_COMMENT, &tmp); sbuf_cat(dest, tmp); break; case 'w': pkg_get(pkg, PKG_WWW, &tmp); sbuf_cat(dest, tmp); break; case 'a': pkg_get(pkg, PKG_AUTOMATIC, &automatic); sbuf_printf(dest, "%d", automatic); break; case 's': qstr++; pkg_get(pkg, PKG_FLATSIZE, &flatsize); if (qstr[0] == 'h') { humanize_number(size, sizeof(size), flatsize, "B", HN_AUTOSCALE, 0); sbuf_cat(dest, size); } else if (qstr[0] == 'b') { sbuf_printf(dest, "%" PRId64, flatsize); } break; case '?': qstr++; switch (qstr[0]) { case 'd': sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_DEPS)); break; case 'r': sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_RDEPS)); break; case 'C': sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_CATEGORIES)); break; case 'F': sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_FILES)); break; case 'O': sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_OPTIONS)); break; case 'D': sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_DIRS)); break; case 'L': sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_LICENSES)); break; case 'U': sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_USERS)); break; case 'G': sbuf_printf(dest, "%d", !pkg_list_is_empty(pkg, PKG_GROUPS)); break; } break; case 'l': pkg_get(pkg, PKG_LICENSE_LOGIC, &licenselogic); switch (licenselogic) { case LICENSE_SINGLE: sbuf_cat(dest, "single"); break; case LICENSE_OR: sbuf_cat(dest, "or"); break; case LICENSE_AND: sbuf_cat(dest, "and"); break; } break; case 'd': qstr++; if (qstr[0] == 'n') sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_NAME)); else if (qstr[0] == 'o') sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_ORIGIN)); else if (qstr[0] == 'v') sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_VERSION)); break; case 'r': qstr++; if (qstr[0] == 'n') sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_NAME)); else if (qstr[0] == 'o') sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_ORIGIN)); else if (qstr[0] == 'v') sbuf_cat(dest, pkg_dep_get((struct pkg_dep *)data, PKG_DEP_VERSION)); break; case 'C': sbuf_cat(dest, pkg_category_name((struct pkg_category *)data)); break; case 'F': qstr++; if (qstr[0] == 'p') sbuf_cat(dest, pkg_file_get((struct pkg_file *)data, PKG_FILE_PATH)); else if (qstr[0] == 's') sbuf_cat(dest, pkg_file_get((struct pkg_file *)data, PKG_FILE_SUM)); break; case 'S': sbuf_cat(dest, pkg_script_data((struct pkg_script *)data)); break; case 'O': qstr++; if (qstr[0] == 'k') sbuf_cat(dest, pkg_option_opt((struct pkg_option *)data)); else if (qstr[0] == 'v') sbuf_cat(dest, pkg_option_value((struct pkg_option *)data)); break; case 'D': sbuf_cat(dest, pkg_dir_path((struct pkg_dir *)data)); break; case 'L': sbuf_cat(dest, pkg_license_name((struct pkg_license *)data)); break; case 'U': sbuf_cat(dest, pkg_user_name((struct pkg_user *)data)); break; case 'G': sbuf_cat(dest, pkg_group_name((struct pkg_group *)data)); break; case '%': sbuf_putc(dest, '%'); break; } } else if (qstr[0] == '\\') { qstr++; switch (qstr[0]) { case 'n': sbuf_putc(dest, '\n'); break; case 'a': sbuf_putc(dest, '\a'); break; case 'b': sbuf_putc(dest, '\b'); break; case 'f': sbuf_putc(dest, '\f'); break; case 'r': sbuf_putc(dest, '\r'); break; case '\\': sbuf_putc(dest, '\\'); break; case 't': sbuf_putc(dest, '\t'); break; } } else { sbuf_putc(dest, qstr[0]); } qstr++; } sbuf_finish(dest); }
int format_sql_condition(const char *str, struct sbuf *sqlcond, bool for_remote) { state_t state = NONE; unsigned int bracket_level = 0; const char *sqlop; sbuf_cat(sqlcond, " WHERE "); while (str[0] != '\0') { if (state == NONE) { if (str[0] == '%') { str++; switch (str[0]) { case 'n': sbuf_cat(sqlcond, "name"); state = OPERATOR_STRING; break; case 'o': sbuf_cat(sqlcond, "origin"); state = OPERATOR_STRING; break; case 'p': sbuf_cat(sqlcond, "prefix"); state = OPERATOR_STRING; break; case 'm': sbuf_cat(sqlcond, "maintainer"); state = OPERATOR_STRING; break; case 'c': sbuf_cat(sqlcond, "comment"); state = OPERATOR_STRING; break; case 'w': sbuf_cat(sqlcond, "www"); state = OPERATOR_STRING; break; case 's': sbuf_cat(sqlcond, "flatsize"); state = OPERATOR_INT; break; case 'a': if (for_remote) goto bad_option; sbuf_cat(sqlcond, "automatic"); state = OPERATOR_INT; break; case 'q': sbuf_cat(sqlcond, "arch"); state = OPERATOR_STRING; break; case 'k': if (for_remote) goto bad_option; sbuf_cat(sqlcond, "locked"); state = OPERATOR_INT; break; case 'M': if (for_remote) goto bad_option; sbuf_cat(sqlcond, "message"); state = OPERATOR_STRING; break; case 't': if (for_remote) goto bad_option; sbuf_cat(sqlcond, "time"); state = OPERATOR_INT; break; case 'e': sbuf_cat(sqlcond, "desc"); state = OPERATOR_STRING; break; case '#': /* FALLTHROUGH */ case '?': sqlop = (str[0] == '#' ? "COUNT(*)" : "COUNT(*) > 0"); str++; switch (str[0]) { case 'd': sbuf_printf(sqlcond, "(SELECT %s FROM deps AS d WHERE d.package_id=p.id)", sqlop); break; case 'r': sbuf_printf(sqlcond, "(SELECT %s FROM deps AS d WHERE d.origin=p.origin)", sqlop); break; case 'C': sbuf_printf(sqlcond, "(SELECT %s FROM pkg_categories AS d WHERE d.package_id=p.id)", sqlop); break; case 'F': if (for_remote) goto bad_option; sbuf_printf(sqlcond, "(SELECT %s FROM files AS d WHERE d.package_id=p.id)", sqlop); break; case 'O': sbuf_printf(sqlcond, "(SELECT %s FROM pkg_option AS d WHERE d.package_id=p.id)", sqlop); break; case 'D': if (for_remote) goto bad_option; sbuf_printf(sqlcond, "(SELECT %s FROM pkg_directories AS d WHERE d.package_id=p.id)", sqlop); break; case 'L': sbuf_printf(sqlcond, "(SELECT %s FROM pkg_licenses AS d WHERE d.package_id=p.id)", sqlop); break; case 'U': if (for_remote) goto bad_option; sbuf_printf(sqlcond, "(SELECT %s FROM pkg_users AS d WHERE d.package_id=p.id)", sqlop); break; case 'G': if (for_remote) goto bad_option; sbuf_printf(sqlcond, "(SELECT %s FROM pkg_groups AS d WHERE d.package_id=p.id)", sqlop); break; case 'B': sbuf_printf(sqlcond, "(SELECT %s FROM pkg_shlibs_required AS d WHERE d.package_id=p.id)", sqlop); break; case 'b': sbuf_printf(sqlcond, "(SELECT %s FROM pkg_shlibs_provided AS d WHERE d.package_id=p.id)", sqlop); break; case 'A': sbuf_printf(sqlcond, "(SELECT %s FROM pkg_annotation AS d WHERE d.package_id=p.id)", sqlop); break; default: goto bad_option; } state = OPERATOR_INT; break; default: bad_option: fprintf(stderr, "malformed evaluation string\n"); return (EPKG_FATAL); } } else { switch (str[0]) { case '(': bracket_level++; sbuf_putc(sqlcond, str[0]); break; case ' ': case '\t': break; default: fprintf(stderr, "unexpected character: %c\n", str[0]); return (EPKG_FATAL); } } } else if (state == POST_EXPR) { switch (str[0]) { case ')': if (bracket_level == 0) { fprintf(stderr, "too many closing brackets.\n"); return (EPKG_FATAL); } bracket_level--; sbuf_putc(sqlcond, str[0]); break; case ' ': case '\t': break; case '|': if (str[1] == '|') { str++; state = NONE; sbuf_cat(sqlcond, " OR "); break; } else { fprintf(stderr, "unexpected character %c\n", str[1]); return (EPKG_FATAL); } case '&': if (str[1] == '&') { str++; state = NONE; sbuf_cat(sqlcond, " AND "); break; } else { fprintf(stderr, "unexpected character %c\n", str[1]); return (EPKG_FATAL); } default: fprintf(stderr, "unexpected character %c\n", str[0]); return (EPKG_FATAL); } } else if (state == OPERATOR_STRING || state == OPERATOR_INT) { /* only operators or space are allowed here */ if (isspace(str[0])) { /* do nothing */ } else if (str[0] == '~' ) { if (state != OPERATOR_STRING) { fprintf(stderr, "~ expected only for string testing\n"); return (EPKG_FATAL); } state = NEXT_IS_STRING; sbuf_cat(sqlcond, " GLOB "); } else if (str[0] == '>' || str[0] == '<') { if (state != OPERATOR_INT) { fprintf(stderr, "> expected only for integers\n"); return (EPKG_FATAL); } state = NEXT_IS_INT; sbuf_putc(sqlcond, str[0]); if (str[1] == '=') { str++; sbuf_putc(sqlcond, str[0]); } } else if (str[0] == '=') { if (state == OPERATOR_STRING) { state = NEXT_IS_STRING; } else { state = NEXT_IS_INT; } sbuf_putc(sqlcond, str[0]); if (str[1] == '=') { str++; sbuf_putc(sqlcond, str[0]); } } else if (str[0] == '!') { if (str[1] != '=') { fprintf(stderr, "expecting = after !\n"); return (EPKG_FATAL); } if (state == OPERATOR_STRING) { state = NEXT_IS_STRING; } else { state = NEXT_IS_INT; } sbuf_putc(sqlcond, str[0]); str++; sbuf_putc(sqlcond, str[0]); } else { fprintf(stderr, "an operator is expected, got %c\n", str[0]); return (EPKG_FATAL); } } else if (state == NEXT_IS_STRING || state == NEXT_IS_INT) { if (isspace(str[0])) { /* do nothing */ } else { if (state == NEXT_IS_STRING) { if (str[0] == '"') { state = QUOTEDSTRING; } else if (str[0] == '\'') { state = SQUOTEDSTRING; } else { state = STRING; str--; } sbuf_putc(sqlcond, '\''); } else { if (!isdigit(str[0])) { fprintf(stderr, "a number is expected, got: %c\n", str[0]); return (EPKG_FATAL); } state = INT; sbuf_putc(sqlcond, str[0]); } } } else if (state == INT) { if (!isdigit(str[0])) { state = POST_EXPR; str--; } else { sbuf_putc(sqlcond, str[0]); } } else if (state == STRING || state == QUOTEDSTRING || state == SQUOTEDSTRING) { if ((state == STRING && isspace(str[0])) || (state == QUOTEDSTRING && str[0] == '"') || (state == SQUOTEDSTRING && str[0] == '\'')) { sbuf_putc(sqlcond, '\''); state = POST_EXPR; } else { sbuf_putc(sqlcond, str[0]); if (str[0] == '\'') sbuf_putc(sqlcond, str[0]); else if (str[0] == '%' && for_remote) sbuf_putc(sqlcond, str[0]); } } str++; } if (state == STRING) { sbuf_putc(sqlcond, '\''); state = POST_EXPR; } if (state != POST_EXPR && state != INT) { fprintf(stderr, "unexpected end of expression\n"); return (EPKG_FATAL); } else if (bracket_level > 0) { fprintf(stderr, "unexpected end of expression (too many open brackets)\n"); return (EPKG_FATAL); } return (EPKG_OK); }
int sys_abort2(struct thread *td, struct abort2_args *uap) { struct proc *p = td->td_proc; struct sbuf *sb; void *uargs[16]; int error, i, sig; /* * Do it right now so we can log either proper call of abort2(), or * note, that invalid argument was passed. 512 is big enough to * handle 16 arguments' descriptions with additional comments. */ sb = sbuf_new(NULL, NULL, 512, SBUF_FIXEDLEN); sbuf_clear(sb); sbuf_printf(sb, "%s(pid %d uid %d) aborted: ", p->p_comm, p->p_pid, td->td_ucred->cr_uid); /* * Since we can't return from abort2(), send SIGKILL in cases, where * abort2() was called improperly */ sig = SIGKILL; /* Prevent from DoSes from user-space. */ if (uap->nargs < 0 || uap->nargs > 16) goto out; if (uap->nargs > 0) { if (uap->args == NULL) goto out; error = copyin(uap->args, uargs, uap->nargs * sizeof(void *)); if (error != 0) goto out; } /* * Limit size of 'reason' string to 128. Will fit even when * maximal number of arguments was chosen to be logged. */ if (uap->why != NULL) { error = sbuf_copyin(sb, uap->why, 128); if (error < 0) goto out; } else { sbuf_printf(sb, "(null)"); } if (uap->nargs > 0) { sbuf_printf(sb, "("); for (i = 0;i < uap->nargs; i++) sbuf_printf(sb, "%s%p", i == 0 ? "" : ", ", uargs[i]); sbuf_printf(sb, ")"); } /* * Final stage: arguments were proper, string has been * successfully copied from userspace, and copying pointers * from user-space succeed. */ sig = SIGABRT; out: if (sig == SIGKILL) { sbuf_trim(sb); sbuf_printf(sb, " (Reason text inaccessible)"); } sbuf_cat(sb, "\n"); sbuf_finish(sb); log(LOG_INFO, "%s", sbuf_data(sb)); sbuf_delete(sb); exit1(td, W_EXITCODE(0, sig)); return (0); }
char * t_rename_eval(struct t_tune *tune, const struct t_rename_pattern *pattern) { struct t_rename_token *token; struct sbuf *sb = NULL; struct t_taglist *tlist = NULL, *l = NULL; char *s = NULL, *ret; assert(tune != NULL); assert(pattern != NULL); sb = sbuf_new_auto(); if (sb == NULL) goto error; tlist = t_tune_tags(tune); if (tlist == NULL) goto error; TAILQ_FOREACH(token, pattern, entries) { if (token->is_tag) { l = t_taglist_find_all(tlist, token->value); if (l == NULL) goto error; if (l->count > 0) { /* tag exist */ if ((s = t_taglist_join(l, " + ")) == NULL) goto error; if (l->count > 1) { warnx("%s: has many `%s' tags, joined with `+'", t_tune_path(tune), token->value); } } t_taglist_delete(l); l = NULL; if (s != NULL) { char *slash = strchr(s, '/'); /* check for slash in tag value */ if (slash != NULL) { warnx("%s: tag `%s' has / in value, replacing by `-'", t_tune_path(tune), token->value); do { *slash = '-'; slash = strchr(slash, '/'); } while (slash != NULL); } } } if (s != NULL) { (void)sbuf_cat(sb, s); free(s); s = NULL; } else (void)sbuf_cat(sb, token->value); } ret = NULL; if (sbuf_len(sb) > MAXPATHLEN) warnx("t_rename_eval result is too long (>MAXPATHLEN)"); else { if (sbuf_finish(sb) != -1) ret = strdup(sbuf_data(sb)); } sbuf_delete(sb); t_taglist_delete(tlist); return (ret); error: free(s); t_taglist_delete(l); sbuf_delete(sb); t_taglist_delete(tlist); return (NULL); }
static void pipeevent(struct pkg_event *ev) { struct pkg *pkg = NULL; struct pkg_dep *dep = NULL; struct sbuf *msg, *buf; const char *message; const char *name, *version, *newversion; if (eventpipe < 0) return; msg = sbuf_new_auto(); buf = sbuf_new_auto(); switch(ev->type) { case PKG_EVENT_ERRNO: sbuf_printf(msg, "{ \"type\": \"ERROR\", " "\"data\": {" "\"msg\": \"%s(%s): %s\"," "\"errno\": %d}}", sbuf_json_escape(buf, ev->e_errno.func), sbuf_json_escape(buf, ev->e_errno.arg), sbuf_json_escape(buf, strerror(ev->e_errno.no)), ev->e_errno.no); break; case PKG_EVENT_ERROR: sbuf_printf(msg, "{ \"type\": \"ERROR\", " "\"data\": {\"msg\": \"%s\"}}", sbuf_json_escape(buf, ev->e_pkg_error.msg)); break; case PKG_EVENT_DEVELOPER_MODE: sbuf_printf(msg, "{ \"type\": \"ERROR\", " "\"data\": {\"msg\": \"DEVELOPER_MODE: %s\"}}", sbuf_json_escape(buf, ev->e_pkg_error.msg)); break; case PKG_EVENT_FETCHING: sbuf_printf(msg, "{ \"type\": \"INFO_FETCH\", " "\"data\": { " "\"url\": \"%s\", " "\"fetched\": %" PRId64 ", " "\"total\": %" PRId64 "}}", sbuf_json_escape(buf, ev->e_fetching.url), ev->e_fetching.done, ev->e_fetching.total ); break; case PKG_EVENT_INSTALL_BEGIN: pkg_get(ev->e_install_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_BEGIN\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\"" "}}", name, version ); break; case PKG_EVENT_INSTALL_FINISHED: pkg_get(ev->e_install_finished.pkg, PKG_MESSAGE, &message, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"INFO_INSTALL_FINISHED\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\", " "\"message\": \"%s\"" "}}", name, version, sbuf_json_escape(buf, message)); break; case PKG_EVENT_INTEGRITYCHECK_BEGIN: sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_BEGIN\", " "\"data\": {}}"); break; case PKG_EVENT_INTEGRITYCHECK_FINISHED: sbuf_printf(msg, "{ \"type\": \"INFO_INTEGRITYCHECK_FINISHED\", " "\"data\": {}}"); break; case PKG_EVENT_DEINSTALL_BEGIN: pkg_get(ev->e_deinstall_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_BEGIN\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\"" "}}", name, version); break; case PKG_EVENT_DEINSTALL_FINISHED: pkg_get(ev->e_deinstall_finished.pkg, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"INFO_DEINSTALL_FINISHED\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\"" "}}", name, version); break; case PKG_EVENT_UPGRADE_BEGIN: pkg_get(ev->e_upgrade_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version, PKG_NEWVERSION, &newversion); sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_BEGIN\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\" ," "\"pkgnewversion\": \"%s\"" "}}", name, version, newversion); break; case PKG_EVENT_UPGRADE_FINISHED: pkg_get(ev->e_upgrade_finished.pkg, PKG_NAME, &name, PKG_VERSION, &version, PKG_NEWVERSION, &newversion); sbuf_printf(msg, "{ \"type\": \"INFO_UPGRADE_FINISHED\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\" ," "\"pkgnewversion\": \"%s\"" "}}", name, version, newversion); break; case PKG_EVENT_LOCKED: pkg_get(ev->e_locked.pkg, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"ERROR_LOCKED\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\"" "}}", name, version); break; case PKG_EVENT_REQUIRED: pkg_get(ev->e_required.pkg, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"ERROR_REQUIRED\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\", " "\"force\": %s, " "\"required_by\": [", name, version, ev->e_required.force == 1 ? "true": "false"); while (pkg_rdeps(pkg, &dep) == EPKG_OK) sbuf_printf(msg, "{ \"pkgname\": \"%s\", " "\"pkgversion\": \"%s\" }, ", pkg_dep_name(dep), pkg_dep_version(dep)); sbuf_setpos(msg, sbuf_len(msg) - 2); sbuf_cat(msg, "]}}"); break; case PKG_EVENT_ALREADY_INSTALLED: pkg_get(ev->e_already_installed.pkg, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"ERROR_ALREADY_INSTALLED\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\"" "}}", name, version); break; case PKG_EVENT_MISSING_DEP: sbuf_printf(msg, "{ \"type\": \"ERROR_MISSING_DEP\", " "\"data\": { " "\"depname\": \"%s\", " "\"depversion\": \"%s\"" "}}" , pkg_dep_name(ev->e_missing_dep.dep), pkg_dep_version(ev->e_missing_dep.dep)); break; case PKG_EVENT_NOREMOTEDB: sbuf_printf(msg, "{ \"type\": \"ERROR_NOREMOTEDB\", " "\"data\": { " "\"url\": \"%s\" " "}}" , ev->e_remotedb.repo); break; case PKG_EVENT_NOLOCALDB: sbuf_printf(msg, "{ \"type\": \"ERROR_NOLOCALDB\", " "\"data\": {} "); break; case PKG_EVENT_NEWPKGVERSION: sbuf_printf(msg, "{ \"type\": \"INFO_NEWPKGVERSION\", " "\"data\": {} "); break; case PKG_EVENT_FILE_MISMATCH: pkg_get(ev->e_file_mismatch.pkg, PKG_NAME, &name, PKG_VERSION, &version); sbuf_printf(msg, "{ \"type\": \"ERROR_FILE_MISMATCH\", " "\"data\": { " "\"pkgname\": \"%s\", " "\"pkgversion\": \"%s\", " "\"path\": \"%s\"" "}}", name, version, sbuf_json_escape(buf, pkg_file_path(ev->e_file_mismatch.file))); break; case PKG_EVENT_PLUGIN_ERRNO: sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", " "\"data\": {" "\"plugin\": \"%s\", " "\"msg\": \"%s(%s): %s\"," "\"errno\": %d" "}}", pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME), sbuf_json_escape(buf, ev->e_plugin_errno.func), sbuf_json_escape(buf, ev->e_plugin_errno.arg), sbuf_json_escape(buf, strerror(ev->e_plugin_errno.no)), ev->e_plugin_errno.no); break; case PKG_EVENT_PLUGIN_ERROR: sbuf_printf(msg, "{ \"type\": \"ERROR_PLUGIN\", " "\"data\": {" "\"plugin\": \"%s\", " "\"msg\": \"%s\"" "}}", pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME), sbuf_json_escape(buf, ev->e_plugin_error.msg)); break; case PKG_EVENT_PLUGIN_INFO: sbuf_printf(msg, "{ \"type\": \"INFO_PLUGIN\", " "\"data\": {" "\"plugin\": \"%s\", " "\"msg\": \"%s\"" "}}", pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME), sbuf_json_escape(buf, ev->e_plugin_info.msg)); break; default: break; } sbuf_finish(msg); dprintf(eventpipe, "%s\n", sbuf_data(msg)); sbuf_delete(msg); sbuf_delete(buf); }
int exec_add(int argc, char **argv) { struct pkgdb *db = NULL; struct sbuf *failedpkgs = NULL; char path[MAXPATHLEN + 1]; char *file; int retcode; int ch; int i; int failedpkgcount = 0; pkg_flags f = PKG_FLAG_NONE; struct pkg_manifest_key *keys = NULL; while ((ch = getopt(argc, argv, "IAfq")) != -1) { switch (ch) { case 'I': f |= PKG_ADD_NOSCRIPT; break; case 'A': f |= PKG_FLAG_AUTOMATIC; break; case 'f': f |= PKG_FLAG_FORCE; break; case 'q': quiet = true; break; default: usage_add(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc < 1) { usage_add(); return (EX_USAGE); } retcode = pkgdb_access(PKGDB_MODE_READ | PKGDB_MODE_WRITE | PKGDB_MODE_CREATE, PKGDB_DB_LOCAL); if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privilege to add packages"); return (EX_NOPERM); } else if (retcode != EPKG_OK) return (EX_IOERR); if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) return (EX_IOERR); failedpkgs = sbuf_new_auto(); pkg_manifest_keys_new(&keys); for (i = 0; i < argc; i++) { if (is_url(argv[i]) == EPKG_OK) { snprintf(path, sizeof(path), "./%s", basename(argv[i])); if ((retcode = pkg_fetch_file(NULL, argv[i], path, 0)) != EPKG_OK) break; file = path; } else { file = argv[i]; if (access(file, F_OK) != 0) { warn("%s",file); if (errno == ENOENT) warnx("Did you mean 'pkg install %s'?", file); sbuf_cat(failedpkgs, argv[i]); if (i != argc - 1) sbuf_printf(failedpkgs, ", "); failedpkgcount++; continue; } } if ((retcode = pkg_add(db, file, f, keys)) != EPKG_OK) { sbuf_cat(failedpkgs, argv[i]); if (i != argc - 1) sbuf_printf(failedpkgs, ", "); failedpkgcount++; } } pkg_manifest_keys_free(keys); pkgdb_close(db); if(failedpkgcount > 0) { sbuf_finish(failedpkgs); printf("\nFailed to install the following %d package(s): %s\n", failedpkgcount, sbuf_data(failedpkgs)); retcode = EPKG_FATAL; } sbuf_delete(failedpkgs); if (messages != NULL) { sbuf_finish(messages); printf("%s", sbuf_data(messages)); } return (retcode == EPKG_OK ? EX_OK : EX_SOFTWARE); }
int main(int argc, char *argv[]) { struct sbuf *cmdbuf; long arg_max; int ch, debug, i, magic, n, nargs, offset, rval; size_t cmdsize; char *cmd, *name, *p, *shell, *slashp, *tmpshell; debug = 0; magic = '%'; /* Default magic char is `%'. */ nargs = -1; while ((ch = getopt(argc, argv, "a:d0123456789")) != -1) switch (ch) { case 'a': if (optarg[1] != '\0') errx(1, "illegal magic character specification"); magic = optarg[0]; break; case 'd': debug = 1; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (nargs != -1) errx(1, "only one -# argument may be specified"); nargs = optopt - '0'; break; default: usage(); } argc -= optind; argv += optind; if (argc < 2) usage(); /* * The command to run is argv[0], and the args are argv[1..]. * Look for %digit references in the command, remembering the * largest one. */ for (n = 0, p = argv[0]; *p != '\0'; ++p) if (p[0] == magic && isdigit(p[1]) && p[1] != '0') { ++p; if (p[0] - '0' > n) n = p[0] - '0'; } /* * Figure out the shell and name arguments to pass to execl() * in exec_shell(). Always malloc() shell and just set name * to point at the last part of shell if there are any backslashes, * otherwise just set it to point at the space malloc()'d. If * SHELL environment variable exists, replace contents of * shell with it. */ shell = name = NULL; tmpshell = getenv("SHELL"); shell = (tmpshell != NULL) ? strdup(tmpshell) : strdup(_PATH_BSHELL); if (shell == NULL) err(1, "strdup() failed"); slashp = strrchr(shell, '/'); name = (slashp != NULL) ? slashp + 1 : shell; /* * If there were any %digit references, then use those, otherwise * build a new command string with sufficient %digit references at * the end to consume (nargs) arguments each time round the loop. * Allocate enough space to hold the maximum command. Save the * size to pass to snprintf(). */ cmdsize = sizeof(EXEC) - 1 + strlen(argv[0]) + 9 * (sizeof(" %1") - 1) + 1; if ((cmd = malloc(cmdsize)) == NULL) err(1, NULL); if (n == 0) { /* If nargs not set, default to a single argument. */ if (nargs == -1) nargs = 1; p = cmd; offset = snprintf(cmd, cmdsize, EXEC "%s", argv[0]); if ((size_t)offset >= cmdsize) errx(1, "snprintf() failed"); p += offset; cmdsize -= offset; for (i = 1; i <= nargs; i++) { offset = snprintf(p, cmdsize, " %c%d", magic, i); if ((size_t)offset >= cmdsize) errx(1, "snprintf() failed"); p += offset; cmdsize -= offset; } /* * If nargs set to the special value 0, eat a single * argument for each command execution. */ if (nargs == 0) nargs = 1; } else { offset = snprintf(cmd, cmdsize, EXEC "%s", argv[0]); if ((size_t)offset >= cmdsize) errx(1, "snprintf() failed"); nargs = n; } cmdbuf = sbuf_new(NULL, NULL, 1024, SBUF_AUTOEXTEND); if (cmdbuf == NULL) err(1, NULL); arg_max = sysconf(_SC_ARG_MAX); /* * (argc) and (argv) are still offset by one to make it simpler to * expand %digit references. At the end of the loop check for (argc) * equals 1 means that all the (argv) has been consumed. */ for (rval = 0; argc > nargs; argc -= nargs, argv += nargs) { sbuf_clear(cmdbuf); /* Expand command argv references. */ for (p = cmd; *p != '\0'; ++p) { if (p[0] == magic && isdigit(p[1]) && p[1] != '0') { if (sbuf_cat(cmdbuf, argv[(++p)[0] - '0']) == -1) errc(1, ENOMEM, "sbuf"); } else { if (sbuf_putc(cmdbuf, *p) == -1) errc(1, ENOMEM, "sbuf"); } if (sbuf_len(cmdbuf) > arg_max) errc(1, E2BIG, NULL); } /* Terminate the command string. */ sbuf_finish(cmdbuf); /* Run the command. */ if (debug) (void)printf("%s\n", sbuf_data(cmdbuf)); else if (exec_shell(sbuf_data(cmdbuf), shell, name)) rval = 1; } if (argc != 1) errx(1, "expecting additional argument%s after \"%s\"", (nargs - argc) ? "s" : "", argv[argc - 1]); free(cmd); sbuf_delete(cmdbuf); free(shell); exit(rval); }
int pkg_old_emit_content(struct pkg *pkg, char **dest) { struct sbuf *content = sbuf_new_auto(); struct pkg_dep *dep = NULL; struct pkg_file *file = NULL; struct pkg_dir *dir = NULL; struct pkg_option *option = NULL; char option_type = 0; pkg_sbuf_printf(content, "@comment PKG_FORMAT_REVISION:1.1\n" "@name %n-%v\n" "@comment ORIGIN:%o\n" "@cwd %p\n" /* hack because we can recreate the prefix split or origin */ "@cwd /\n", pkg, pkg, pkg, pkg); while (pkg_deps(pkg, &dep) == EPKG_OK) { sbuf_printf(content, "@pkgdep %s-%s\n" "@comment DEPORIGIN:%s\n", pkg_dep_name(dep), pkg_dep_version(dep), pkg_dep_origin(dep)); } while (pkg_files(pkg, &file) == EPKG_OK) { sbuf_printf(content, "%s\n" "@comment MD5:%s\n", file->path + 1, file->sum); } while (pkg_dirs(pkg, &dir) == EPKG_OK) { sbuf_printf(content, "@unexec /sbin/rmdir \"%s\" 2>/dev/null\n", dir->path); } sbuf_printf(content, "@comment OPTIONS:"); while (pkg_options(pkg, &option) == EPKG_OK) { /* Add space for previous option, if not the first. */ if (option_type != 0) sbuf_cat(content, " "); if (strcmp(pkg_option_value(option), "on") == 0) option_type = '+'; else option_type = '-'; sbuf_printf(content, "%c%s", option_type, pkg_option_opt(option)); } sbuf_printf(content, "\n"); sbuf_finish(content); *dest = strdup(sbuf_get(content)); sbuf_delete(content); return (EPKG_OK); }
int pkg_register_old(struct pkg *pkg) { FILE *fp; char *content; const char *pkgdbdir, *tmp; char path[MAXPATHLEN]; struct sbuf *install_script = sbuf_new_auto(); struct sbuf *deinstall_script = sbuf_new_auto(); struct pkg_dep *dep = NULL; pkg_to_old(pkg); pkg_old_emit_content(pkg, &content); pkgdbdir = pkg_object_string(pkg_config_get("PKG_DBDIR")); pkg_snprintf(path, sizeof(path), "%S/%n-%v", pkgdbdir, pkg, pkg); mkdir(path, 0755); pkg_snprintf(path, sizeof(path), "%S/%n-%v/+CONTENTS", pkgdbdir, pkg, pkg); fp = fopen(path, "w"); fputs(content, fp); fclose(fp); pkg_snprintf(path, sizeof(path), "%S/%n-%v/+DESC", pkgdbdir, pkg, pkg); fp = fopen(path, "w"); pkg_fprintf(fp, "%e", pkg); fclose(fp); pkg_snprintf(path, sizeof(path), "%s/%n-%v/+COMMENT", pkgdbdir, pkg, pkg); fp = fopen(path, "w"); pkg_fprintf(fp, "%c\n", pkg); fclose(fp); if (pkg_has_message(pkg)) { pkg_snprintf(path, sizeof(path), "%s/%n-%v/+DISPLAY", pkgdbdir, pkg, pkg); fp = fopen(path, "w"); pkg_fprintf(fp, "%M", pkg); fclose(fp); } sbuf_clear(install_script); tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_INSTALL); if (tmp != NULL && *tmp != '\0') { if (sbuf_len(install_script) == 0) sbuf_cat(install_script, "#!/bin/sh\n\n"); sbuf_printf(install_script, "if [ \"$2\" = \"PRE-INSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_INSTALL); if (tmp != NULL && *tmp != '\0') { if (sbuf_len(install_script) == 0) sbuf_cat(install_script, "#!/bin/sh\n\n"); sbuf_cat(install_script, tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_INSTALL); if (tmp != NULL && *tmp != '\0') { if (sbuf_len(install_script) == 0) sbuf_cat(install_script, "#!/bin/sh\n\n"); sbuf_printf(install_script, "if [ \"$2\" = \"POST-INSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } if (sbuf_len(install_script) > 0) { sbuf_finish(install_script); pkg_snprintf(path, sizeof(path), "%s/%n-%v/+INSTALL", pkgdbdir, pkg, pkg); fp = fopen(path, "w"); fputs(sbuf_data(install_script), fp); fclose(fp); } sbuf_clear(deinstall_script); tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_DEINSTALL); if (tmp != NULL && *tmp != '\0') { if (sbuf_len(deinstall_script) == 0) sbuf_cat(deinstall_script, "#!/bin/sh\n\n"); sbuf_printf(deinstall_script, "if [ \"$2\" = \"DEINSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_DEINSTALL); if (tmp != NULL && *tmp != '\0') { if (sbuf_len(deinstall_script) == 0) sbuf_cat(deinstall_script, "#!/bin/sh\n\n"); sbuf_cat(deinstall_script, tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_DEINSTALL); if (tmp != NULL && tmp[0] != '\0') { if (sbuf_len(deinstall_script) == 0) sbuf_cat(deinstall_script, "#!/bin/sh\n\n"); sbuf_printf(deinstall_script, "if [ \"$2\" = \"POST-DEINSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } if (sbuf_len(deinstall_script) > 0) { sbuf_finish(deinstall_script); pkg_snprintf(path, sizeof(path), "%s/%n-%v/+DEINSTALL", pkgdbdir, pkg, pkg); fp = fopen(path, "w"); fputs(sbuf_data(deinstall_script), fp); fclose(fp); } while (pkg_deps(pkg, &dep)) { snprintf(path, sizeof(path), "%s/%s-%s/+REQUIRED_BY", pkgdbdir, pkg_dep_name(dep), pkg_dep_version(dep)); fp = fopen(path, "a"); pkg_fprintf(fp, "%n-%v\n", pkg, pkg); fclose(fp); } return (EPKG_OK); }
/* Print data values for variable varid. * * Recursive to handle possibility of variables with multiple * unlimited dimensions, for which the CDL syntax requires use of "{" * and "}" in data section to disambiguate the size of nested records * in a simple linear list of values. */ static int print_rows( int level, /* 0 at top-level, incremented for each recursive level */ int ncid, /* netcdf id */ int varid, /* variable id */ const ncvar_t *vp, /* variable */ size_t ncols, /* number of values in a row */ int rank, /* number of elements in following 3 arrays */ size_t vdims[], /* variable dimension sizes */ size_t cor[], /* corner coordinates */ size_t edg[], /* edges of hypercube */ void *vals, /* allocated buffer for ncols values in a row */ int marks_pending /* number of pending closing "}" record markers */ ) { int d0 = 0; size_t inc = 1; int i; bool_t mark_record = (level > 0 && is_unlim_dim(ncid, vp->dims[level])); safebuf_t *sb = sbuf_new(); if (rank > 0) d0 = vdims[level]; for(i = level + 1; i < rank; i++) { inc *= vdims[i]; } if(mark_record) { /* the whole point of this recursion is printing these "{}" */ lput("{"); marks_pending++; /* matching "}"s to emit after last "row" */ } if(rank - level > 1) { /* this level is just d0 next levels */ size_t *local_cor = emalloc((rank + 1) * sizeof(size_t)); size_t *local_edg = emalloc((rank + 1) * sizeof(size_t)); for(i = 0; i < rank; i++) { local_cor[i] = cor[i]; local_edg[i] = edg[i]; } local_cor[level] = 0; local_edg[level] = 1; for(i = 0; i < d0 - 1; i++) { print_rows(level + 1, ncid, varid, vp, ncols, rank, vdims, local_cor, local_edg, vals, 0); local_cor[level] += 1; } print_rows(level + 1, ncid, varid, vp, ncols, rank, vdims, local_cor, local_edg, vals, marks_pending); free(local_edg); free(local_cor); } else { /* bottom out of recursion */ char *valp = vals; bool_t lastrow; int j; if(formatting_specs.brief_data_cmnts && rank > 1) { annotate_brief(vp, cor, vdims); } NC_CHECK(nc_get_vara(ncid, varid, cor, edg, (void *)valp)); for(i=0; i < d0 - 1; i++) { print_any_val(sb, vp, (void *)valp); valp += vp->tinfo->size; /* next value according to type */ if (formatting_specs.full_data_cmnts) { printf("%s, ", sb->buf); annotate (vp, cor, i); } else { sbuf_cat(sb, ", "); lput(sbuf_str(sb)); } } print_any_val(sb, vp, (void *)valp); /* determine if this is the last row */ lastrow = true; for(j = 0; j < rank - 1; j++) { if (cor[j] != vdims[j] - 1) { lastrow = false; break; } } if (formatting_specs.full_data_cmnts) { for (j = 0; j < marks_pending; j++) { sbuf_cat(sb, "}"); } printf("%s", sbuf_str(sb)); lastdelim (0, lastrow); annotate (vp, cor, i); } else { for (j = 0; j < marks_pending; j++) { sbuf_cat(sb, "}"); } lput(sbuf_str(sb)); lastdelim2 (0, lastrow); } } sbuf_free(sb); return NC_NOERR; }
static int convert_to_old(const char *pkg_add_dbdir, bool dry_run) { struct pkgdb *db = NULL; struct pkg *pkg = NULL; struct pkg_dep *dep = NULL; struct pkgdb_it *it = NULL; char *content, *name, *version, *buf; const char *tmp; int ret = EX_OK; char path[MAXPATHLEN]; int query_flags = PKG_LOAD_DEPS | PKG_LOAD_FILES | PKG_LOAD_DIRS | PKG_LOAD_SCRIPTS | PKG_LOAD_OPTIONS | PKG_LOAD_MTREE | PKG_LOAD_USERS | PKG_LOAD_GROUPS | PKG_LOAD_RDEPS; FILE *fp, *rq; struct sbuf *install_script = sbuf_new_auto(); struct sbuf *deinstall_script = sbuf_new_auto(); if (mkdir(pkg_add_dbdir, 0755) != 0 && errno != EEXIST) err(EX_CANTCREAT, "%s", pkg_add_dbdir); if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) { pkgdb_close(db); return (EX_IOERR); } if ((it = pkgdb_query(db, NULL, MATCH_ALL)) == NULL) { ret = EPKG_FATAL; goto cleanup; } while (pkgdb_it_next(it, &pkg, query_flags) == EPKG_OK) { rq = NULL; pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version); printf("Converting %s-%s...", name, version); if (dry_run) { printf("\n"); continue; } pkg_to_old(pkg); pkg_old_emit_content(pkg, &content); snprintf(path, MAXPATHLEN, "%s/%s-%s", pkg_add_dbdir, name, version); mkdir(path, 0755); snprintf(path, MAXPATHLEN, "%s/%s-%s/+CONTENTS", pkg_add_dbdir, name, version); fp = fopen(path, "w"); fputs(content, fp); fclose(fp); pkg_get(pkg, PKG_DESC, &buf); snprintf(path, MAXPATHLEN, "%s/%s-%s/+DESC", pkg_add_dbdir, name, version); fp = fopen(path, "w"); fputs(buf, fp); fclose(fp); pkg_get(pkg, PKG_COMMENT, &buf); snprintf(path, MAXPATHLEN, "%s/%s-%s/+COMMENT", pkg_add_dbdir, name, version); fp = fopen(path, "w"); fprintf(fp, "%s\n", buf); fclose(fp); pkg_get(pkg, PKG_MESSAGE, &buf); if (buf != NULL && buf[0] != '\0') { snprintf(path, MAXPATHLEN, "%s/%s-%s/+DISPLAY", pkg_add_dbdir, name, version); fp = fopen(path, "w"); fputs(buf, fp); fclose(fp); } pkg_get(pkg, PKG_MTREE, &buf); if (buf != NULL && buf[0] != '\0') { snprintf(path, MAXPATHLEN, "%s/%s-%s/+MTREE_DIRS", pkg_add_dbdir, name, version); fp = fopen(path, "w"); fputs(buf, fp); fclose(fp); } sbuf_clear(install_script); tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_INSTALL); if (tmp != NULL && tmp[0] != '\0') { if (sbuf_len(install_script) == 0) sbuf_cat(install_script, "#!/bin/sh\n\n"); sbuf_printf(install_script, "if [ \"$2\" = \"PRE-INSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_INSTALL); if (tmp != NULL && tmp[0] != '\0') { if (sbuf_len(install_script) == 0) sbuf_cat(install_script, "#!/bin/sh\n\n"); sbuf_cat(install_script, tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_INSTALL); if (tmp != NULL && tmp[0] != '\0') { if (sbuf_len(install_script) == 0) sbuf_cat(install_script, "#!/bin/sh\n\n"); sbuf_printf(install_script, "if [ \"$2\" = \"POST-INSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } if (sbuf_len(install_script) > 0) { sbuf_finish(install_script); snprintf(path, MAXPATHLEN, "%s/%s-%s/+INSTALL", pkg_add_dbdir, name, version); fp = fopen(path, "w"); fputs(sbuf_data(install_script), fp); fclose(fp); } sbuf_clear(deinstall_script); tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_DEINSTALL); if (tmp != NULL && tmp[0] != '\0') { if (sbuf_len(deinstall_script) == 0) sbuf_cat(deinstall_script, "#!/bin/sh\n\n"); sbuf_printf(deinstall_script, "if [ \"$2\" = \"DEINSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_DEINSTALL); if (tmp != NULL && tmp[0] != '\0') { if (sbuf_len(deinstall_script) == 0) sbuf_cat(deinstall_script, "#!/bin/sh\n\n"); sbuf_cat(deinstall_script, tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_DEINSTALL); if (tmp != NULL && tmp[0] != '\0') { if (sbuf_len(deinstall_script) == 0) sbuf_cat(deinstall_script, "#!/bin/sh\n\n"); sbuf_printf(deinstall_script, "if [ \"$2\" = \"POST-DEINSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } if (sbuf_len(deinstall_script) > 0) { sbuf_finish(deinstall_script); snprintf(path, MAXPATHLEN, "%s/%s-%s/+DEINSTALL", pkg_add_dbdir, name, version); fp = fopen(path, "w"); fputs(sbuf_data(deinstall_script), fp); fclose(fp); } snprintf(path, MAXPATHLEN, "%s/%s-%s/+REQUIRED_BY", pkg_add_dbdir, name, version); while (pkg_rdeps(pkg, &dep) == EPKG_OK) { if (rq == NULL) rq = fopen(path, "w"); fprintf(rq, "%s-%s\n", pkg_dep_name(dep), pkg_dep_version(dep)); } if (rq != NULL) fclose(rq); printf("done.\n"); free(content); } sbuf_delete(install_script); sbuf_delete(deinstall_script); cleanup: pkg_free(pkg); pkgdb_it_free(it); pkgdb_close(db); return (ret); }
int event_callback(void *data, struct pkg_event *ev) { struct pkg *pkg = NULL, *pkg_new, *pkg_old; int *debug = data; struct pkg_event_conflict *cur_conflict; const char *filename; if (msg_buf == NULL) { msg_buf = sbuf_new_auto(); } /* * If a progressbar has been interrupted by another event, then * we need to add a newline to prevent bad formatting. */ if (progress_started && ev->type != PKG_EVENT_PROGRESS_TICK && !progress_interrupted) { putchar('\n'); progress_interrupted = true; } switch(ev->type) { case PKG_EVENT_ERRNO: warnx("%s(%s): %s", ev->e_errno.func, ev->e_errno.arg, strerror(ev->e_errno.no)); break; case PKG_EVENT_ERROR: warnx("%s", ev->e_pkg_error.msg); break; case PKG_EVENT_NOTICE: if (!quiet) printf("%s\n", ev->e_pkg_notice.msg); break; case PKG_EVENT_DEVELOPER_MODE: warnx("DEVELOPER_MODE: %s", ev->e_pkg_error.msg); break; case PKG_EVENT_UPDATE_ADD: if (quiet || !isatty(STDOUT_FILENO)) break; printf("\rPushing new entries %d/%d", ev->e_upd_add.done, ev->e_upd_add.total); if (ev->e_upd_add.total == ev->e_upd_add.done) printf("\n"); break; case PKG_EVENT_UPDATE_REMOVE: if (quiet || !isatty(STDOUT_FILENO)) break; printf("\rRemoving entries %d/%d", ev->e_upd_remove.done, ev->e_upd_remove.total); if (ev->e_upd_remove.total == ev->e_upd_remove.done) printf("\n"); break; case PKG_EVENT_FETCH_BEGIN: if (quiet) break; filename = strrchr(ev->e_fetching.url, '/'); if (filename != NULL) { filename++; } else { /* * We failed at being smart, so display * the entire url. */ filename = ev->e_fetching.url; } job_status_begin(msg_buf); progress_debit = true; sbuf_printf(msg_buf, "Fetching %s", filename); break; case PKG_EVENT_FETCH_FINISHED: progress_debit = false; break; case PKG_EVENT_INSTALL_BEGIN: if (quiet) break; else { nbdone++; job_status_begin(msg_buf); pkg = ev->e_install_begin.pkg; pkg_sbuf_printf(msg_buf, "Installing %n-%v...\n", pkg, pkg); sbuf_finish(msg_buf); printf("%s", sbuf_data(msg_buf)); } break; case PKG_EVENT_INSTALL_FINISHED: if (quiet) break; pkg = ev->e_install_finished.pkg; if (pkg_has_message(pkg)) { if (messages == NULL) messages = sbuf_new_auto(); pkg_sbuf_printf(messages, "Message for %n-%v:\n%M\n", pkg, pkg, pkg); } break; case PKG_EVENT_EXTRACT_BEGIN: if (quiet) break; else { job_status_begin(msg_buf); pkg = ev->e_install_begin.pkg; pkg_sbuf_printf(msg_buf, "Extracting %n-%v", pkg, pkg); } break; case PKG_EVENT_EXTRACT_FINISHED: break; case PKG_EVENT_ADD_DEPS_BEGIN: ++add_deps_depth; break; case PKG_EVENT_ADD_DEPS_FINISHED: --add_deps_depth; break; case PKG_EVENT_INTEGRITYCHECK_BEGIN: if (quiet) break; printf("Checking integrity..."); break; case PKG_EVENT_INTEGRITYCHECK_FINISHED: if (quiet) break; printf(" done (%d conflicting)\n", ev->e_integrity_finished.conflicting); break; case PKG_EVENT_INTEGRITYCHECK_CONFLICT: if (*debug == 0) break; printf("\nConflict found on path %s between %s and ", ev->e_integrity_conflict.pkg_path, ev->e_integrity_conflict.pkg_uid); cur_conflict = ev->e_integrity_conflict.conflicts; while (cur_conflict) { if (cur_conflict->next) printf("%s, ", cur_conflict->uid); else printf("%s", cur_conflict->uid); cur_conflict = cur_conflict->next; } printf("\n"); break; case PKG_EVENT_DEINSTALL_BEGIN: if (quiet) break; nbdone++; job_status_begin(msg_buf); pkg = ev->e_install_begin.pkg; pkg_sbuf_printf(msg_buf, "Deinstalling %n-%v...\n", pkg, pkg); sbuf_finish(msg_buf); printf("%s", sbuf_data(msg_buf)); break; case PKG_EVENT_DEINSTALL_FINISHED: if (quiet) break; break; case PKG_EVENT_DELETE_FILES_BEGIN: if (quiet) break; else { job_status_begin(msg_buf); pkg = ev->e_install_begin.pkg; pkg_sbuf_printf(msg_buf, "Deleting files for %n-%v", pkg, pkg); } break; case PKG_EVENT_DELETE_FILES_FINISHED: break; case PKG_EVENT_UPGRADE_BEGIN: if (quiet) break; pkg_new = ev->e_upgrade_begin.n; pkg_old = ev->e_upgrade_begin.o; nbdone++; job_status_begin(msg_buf); switch (pkg_version_change_between(pkg_new, pkg_old)) { case PKG_DOWNGRADE: pkg_sbuf_printf(msg_buf, "Downgrading %n from %v to %v...\n", pkg_new, pkg_old, pkg_new); break; case PKG_REINSTALL: pkg_sbuf_printf(msg_buf, "Reinstalling %n-%v...\n", pkg_old, pkg_old); break; case PKG_UPGRADE: pkg_sbuf_printf(msg_buf, "Upgrading %n from %v to %v...\n", pkg_new, pkg_old, pkg_new); break; } sbuf_finish(msg_buf); printf("%s", sbuf_data(msg_buf)); break; case PKG_EVENT_UPGRADE_FINISHED: if (quiet) break; pkg_new = ev->e_upgrade_finished.n; if (pkg_has_message(pkg_new)) { if (messages == NULL) messages = sbuf_new_auto(); pkg_sbuf_printf(messages, "Message for %n-%v:\n %M\n", pkg_new, pkg_new, pkg_new); } break; case PKG_EVENT_LOCKED: pkg = ev->e_locked.pkg; pkg_printf("\n%n-%v is locked and may not be modified\n", pkg, pkg); break; case PKG_EVENT_REQUIRED: pkg = ev->e_required.pkg; pkg_printf("\n%n-%v is required by: %r%{%rn-%rv%| %}", pkg, pkg, pkg); if (ev->e_required.force == 1) fprintf(stderr, ", deleting anyway\n"); else fprintf(stderr, "\n"); break; case PKG_EVENT_ALREADY_INSTALLED: if (quiet) break; pkg = ev->e_already_installed.pkg; pkg_printf("the most recent version of %n-%v is already installed\n", pkg, pkg); break; case PKG_EVENT_NOT_FOUND: printf("Package '%s' was not found in " "the repositories\n", ev->e_not_found.pkg_name); break; case PKG_EVENT_MISSING_DEP: warnx("Missing dependency '%s-%s'", pkg_dep_name(ev->e_missing_dep.dep), pkg_dep_version(ev->e_missing_dep.dep)); break; case PKG_EVENT_NOREMOTEDB: fprintf(stderr, "Unable to open remote database \"%s\". " "Try running '%s update' first.\n", ev->e_remotedb.repo, getprogname()); break; case PKG_EVENT_NOLOCALDB: fprintf(stderr, "Local package database nonexistent!\n"); break; case PKG_EVENT_NEWPKGVERSION: newpkgversion = true; printf("New version of pkg detected; it needs to be " "installed first.\n"); break; case PKG_EVENT_FILE_MISMATCH: pkg = ev->e_file_mismatch.pkg; pkg_fprintf(stderr, "%n-%v: checksum mismatch for %Fn\n", pkg, pkg, ev->e_file_mismatch.file); break; case PKG_EVENT_PLUGIN_ERRNO: warnx("%s: %s(%s): %s", pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME), ev->e_plugin_errno.func, ev->e_plugin_errno.arg, strerror(ev->e_plugin_errno.no)); break; case PKG_EVENT_PLUGIN_ERROR: warnx("%s: %s", pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME), ev->e_plugin_error.msg); break; case PKG_EVENT_PLUGIN_INFO: if (quiet) break; printf("%s: %s\n", pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME), ev->e_plugin_info.msg); break; case PKG_EVENT_INCREMENTAL_UPDATE: if (!quiet) printf("%s repository update completed. %d packages processed.\n", ev->e_incremental_update.reponame, ev->e_incremental_update.processed); break; case PKG_EVENT_DEBUG: fprintf(stderr, "DBG(%d)[%d]> %s\n", ev->e_debug.level, (int)getpid(), ev->e_debug.msg); break; case PKG_EVENT_QUERY_YESNO: return ( ev->e_query_yesno.deft ? query_yesno(true, ev->e_query_yesno.msg, "[Y/n]") : query_yesno(false, ev->e_query_yesno.msg, "[y/N]") ); break; case PKG_EVENT_QUERY_SELECT: return query_select(ev->e_query_select.msg, ev->e_query_select.items, ev->e_query_select.ncnt, ev->e_query_select.deft); break; case PKG_EVENT_SANDBOX_CALL: return ( event_sandboxed_call(ev->e_sandbox_call.call, ev->e_sandbox_call.fd, ev->e_sandbox_call.userdata) ); break; case PKG_EVENT_SANDBOX_GET_STRING: return ( event_sandboxed_get_string(ev->e_sandbox_call_str.call, ev->e_sandbox_call_str.result, ev->e_sandbox_call_str.len, ev->e_sandbox_call_str.userdata) ); break; case PKG_EVENT_PROGRESS_START: progressbar_start(ev->e_progress_start.msg); break; case PKG_EVENT_PROGRESS_TICK: progressbar_tick(ev->e_progress_tick.current, ev->e_progress_tick.total); break; case PKG_EVENT_BACKUP: sbuf_cat(msg_buf, "Backing up"); sbuf_finish(msg_buf); break; case PKG_EVENT_RESTORE: sbuf_cat(msg_buf, "Restoring"); sbuf_finish(msg_buf); break; default: break; } return 0; }
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); }
static void format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, void *data) { char size[7]; const char *tmp; bool tmp2; int64_t flatsize; int64_t timestamp; lic_t licenselogic; sbuf_clear(dest); while (qstr[0] != '\0') { if (qstr[0] == '%') { qstr++; switch (qstr[0]) { case 'n': pkg_get(pkg, PKG_NAME, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'v': pkg_get(pkg, PKG_VERSION, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'o': pkg_get(pkg, PKG_ORIGIN, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'R': pkg_get(pkg, PKG_REPONAME, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'p': pkg_get(pkg, PKG_PREFIX, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'm': pkg_get(pkg, PKG_MAINTAINER, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'c': pkg_get(pkg, PKG_COMMENT, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'w': pkg_get(pkg, PKG_WWW, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'i': pkg_get(pkg, PKG_INFOS, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case 'a': pkg_get(pkg, PKG_AUTOMATIC, &tmp2); sbuf_printf(dest, "%d", tmp2); break; case 'k': pkg_get(pkg, PKG_LOCKED, &tmp2); sbuf_printf(dest, "%d", tmp2); break; case 't': pkg_get(pkg, PKG_TIME, ×tamp); sbuf_printf(dest, "%" PRId64, timestamp); break; case 's': qstr++; pkg_get(pkg, PKG_FLATSIZE, &flatsize); if (qstr[0] == 'h') { humanize_number(size, sizeof(size), flatsize, "B", HN_AUTOSCALE, 0); sbuf_cat(dest, size); } else if (qstr[0] == 'b') { sbuf_printf(dest, "%" PRId64, flatsize); } break; case 'e': pkg_get(pkg, PKG_DESC, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case '?': qstr++; switch (qstr[0]) { case 'd': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DEPS) > 0); break; case 'r': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_RDEPS) > 0); break; case 'C': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_CATEGORIES) > 0); break; case 'F': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_FILES) > 0); break; case 'O': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_OPTIONS) > 0); break; case 'D': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DIRS) > 0); break; case 'L': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_LICENSES) > 0); break; case 'U': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_USERS) > 0); break; case 'G': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_GROUPS) > 0); break; case 'B': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_REQUIRED) > 0); break; case 'b': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_PROVIDED) > 0); break; case 'A': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_ANNOTATIONS) > 0); break; } break; case '#': qstr++; switch (qstr[0]) { case 'd': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DEPS)); break; case 'r': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_RDEPS)); break; case 'C': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_CATEGORIES)); break; case 'F': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_FILES)); break; case 'O': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_OPTIONS)); break; case 'D': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DIRS)); break; case 'L': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_LICENSES)); break; case 'U': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_USERS)); break; case 'G': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_GROUPS)); break; case 'B': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_REQUIRED)); break; case 'b': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_PROVIDED)); break; case 'A': sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_ANNOTATIONS)); break; } break; case 'l': pkg_get(pkg, PKG_LICENSE_LOGIC, &licenselogic); switch (licenselogic) { case LICENSE_SINGLE: sbuf_cat(dest, "single"); break; case LICENSE_OR: sbuf_cat(dest, "or"); break; case LICENSE_AND: sbuf_cat(dest, "and"); break; } break; case 'd': qstr++; if (qstr[0] == 'n') sbuf_cat(dest, pkg_dep_name((struct pkg_dep *)data)); else if (qstr[0] == 'o') sbuf_cat(dest, pkg_dep_origin((struct pkg_dep *)data)); else if (qstr[0] == 'v') sbuf_cat(dest, pkg_dep_version((struct pkg_dep *)data)); break; case 'r': qstr++; if (qstr[0] == 'n') sbuf_cat(dest, pkg_dep_name((struct pkg_dep *)data)); else if (qstr[0] == 'o') sbuf_cat(dest, pkg_dep_origin((struct pkg_dep *)data)); else if (qstr[0] == 'v') sbuf_cat(dest, pkg_dep_version((struct pkg_dep *)data)); break; case 'C': sbuf_cat(dest, pkg_category_name((struct pkg_category *)data)); break; case 'F': qstr++; if (qstr[0] == 'p') sbuf_cat(dest, pkg_file_path((struct pkg_file *)data)); else if (qstr[0] == 's') sbuf_cat(dest, pkg_file_cksum((struct pkg_file *)data)); break; case 'O': qstr++; if (qstr[0] == 'k') sbuf_cat(dest, pkg_option_opt((struct pkg_option *)data)); else if (qstr[0] == 'v') sbuf_cat(dest, pkg_option_value((struct pkg_option *)data)); break; case 'D': sbuf_cat(dest, pkg_dir_path((struct pkg_dir *)data)); break; case 'L': sbuf_cat(dest, pkg_license_name((struct pkg_license *)data)); break; case 'U': sbuf_cat(dest, pkg_user_name((struct pkg_user *)data)); break; case 'G': sbuf_cat(dest, pkg_group_name((struct pkg_group *)data)); break; case 'B': case 'b': sbuf_cat(dest, pkg_shlib_name((struct pkg_shlib *)data)); break; case 'A': qstr++; if (qstr[0] == 't') sbuf_cat(dest, pkg_annotation_tag((struct pkg_note *)data)); else if (qstr[0] == 'v') sbuf_cat(dest, pkg_annotation_value((struct pkg_note *)data)); break; case 'M': pkg_get(pkg, PKG_MESSAGE, &tmp); if (tmp != NULL) sbuf_cat(dest, tmp); break; case '%': sbuf_putc(dest, '%'); break; } } else if (qstr[0] == '\\') { qstr++; switch (qstr[0]) { case 'n': sbuf_putc(dest, '\n'); break; case 'a': sbuf_putc(dest, '\a'); break; case 'b': sbuf_putc(dest, '\b'); break; case 'f': sbuf_putc(dest, '\f'); break; case 'r': sbuf_putc(dest, '\r'); break; case '\\': sbuf_putc(dest, '\\'); break; case 't': sbuf_putc(dest, '\t'); break; } } else { sbuf_putc(dest, qstr[0]); } qstr++; } sbuf_finish(dest); }
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); }
int format_exec_cmd(char **dest, const char *in, const char *prefix, const char *plist_file, char *line, int argc, char **argv) { struct sbuf *buf = sbuf_new_auto(); char path[MAXPATHLEN]; char *cp; size_t sz; while (in[0] != '\0') { if (in[0] != '%') { sbuf_putc(buf, in[0]); in++; continue; } in++; switch(in[0]) { case 'D': sbuf_cat(buf, prefix); break; case 'F': if (plist_file == NULL || plist_file[0] == '\0') { 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 || plist_file[0] == '\0') { 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 || plist_file[0] == '\0') { 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 */ case '#': sbuf_putc(buf, argc); break; default: if ((sz = strspn(in, "0123456789")) > 0) { int pos = strtol(in, NULL, 10); if (pos > argc) { pkg_emit_error("Requesting argument " "%%%d while only %d arguments are" " available", pos, argc); sbuf_finish(buf); sbuf_free(buf); return (EPKG_FATAL); } sbuf_cat(buf, argv[pos -1]); in += sz -1; break; } sbuf_putc(buf, '%'); sbuf_putc(buf, in[0]); break; } in++; } sbuf_finish(buf); *dest = strdup(sbuf_data(buf)); sbuf_free(buf); return (EPKG_OK); }
/* 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); }
int exec_add(int argc, char **argv) { struct pkgdb *db = NULL; struct sbuf *failedpkgs = NULL; char path[MAXPATHLEN]; char *file; int retcode; int ch; int i; int failedpkgcount = 0; pkg_flags f = PKG_FLAG_NONE; struct pkg_manifest_key *keys = NULL; const char *location = NULL; /* options descriptor */ struct option longopts[] = { { "no-scripts", no_argument, NULL, 'I' }, { "automatic", no_argument, NULL, 'A' }, { "force", no_argument, NULL, 'f' }, { "accept-missing", no_argument, NULL, 'M' }, { "quiet", no_argument, NULL, 'q' }, { "relocate", required_argument, NULL, 1 }, { NULL, 0, NULL, 0 } }; while ((ch = getopt_long(argc, argv, "IAfqM", longopts, NULL)) != -1) { switch (ch) { case 'I': f |= PKG_ADD_NOSCRIPT; break; case 'A': f |= PKG_ADD_AUTOMATIC; break; case 'f': f |= PKG_ADD_FORCE; force = true; break; case 'M': f |= PKG_ADD_FORCE_MISSING; break; case 'q': quiet = true; break; case 1: location = optarg; break; default: usage_add(); return (EX_USAGE); } } argc -= optind; argv += optind; if (argc < 1) { usage_add(); return (EX_USAGE); } retcode = pkgdb_access(PKGDB_MODE_READ | PKGDB_MODE_WRITE | PKGDB_MODE_CREATE, PKGDB_DB_LOCAL); if (retcode == EPKG_ENOACCESS) { warnx("Insufficient privileges to add packages"); return (EX_NOPERM); } else if (retcode != EPKG_OK) return (EX_IOERR); if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) return (EX_IOERR); if (pkgdb_obtain_lock(db, PKGDB_LOCK_EXCLUSIVE) != EPKG_OK) { pkgdb_close(db); warnx("Cannot get an exclusive lock on a database, it is locked by another process"); return (EX_TEMPFAIL); } failedpkgs = sbuf_new_auto(); pkg_manifest_keys_new(&keys); for (i = 0; i < argc; i++) { if (is_url(argv[i]) == EPKG_OK) { snprintf(path, sizeof(path), "%s/%s.XXXXX", getenv("TMPDIR") != NULL ? getenv("TMPDIR") : "/tmp", basename(argv[i])); if ((retcode = pkg_fetch_file(NULL, argv[i], path, 0)) != EPKG_OK) break; file = path; } else { file = argv[i]; /* Special case: treat a filename of "-" as meaning 'read from stdin.' It doesn't make sense to have a filename of "-" more than once per command line, but we aren't testing for that at the moment */ if (strcmp(file, "-") != 0 && access(file, F_OK) != 0) { warn("%s", file); if (errno == ENOENT) warnx("Was 'pkg install %s' meant?", file); sbuf_cat(failedpkgs, argv[i]); if (i != argc - 1) sbuf_printf(failedpkgs, ", "); failedpkgcount++; continue; } } if ((retcode = pkg_add(db, file, f, keys, location)) != EPKG_OK) { sbuf_cat(failedpkgs, argv[i]); if (i != argc - 1) sbuf_printf(failedpkgs, ", "); failedpkgcount++; } if (is_url(argv[i]) == EPKG_OK) unlink(file); } pkg_manifest_keys_free(keys); pkgdb_release_lock(db, PKGDB_LOCK_EXCLUSIVE); pkgdb_close(db); if(failedpkgcount > 0) { sbuf_finish(failedpkgs); printf("\nFailed to install the following %d package(s): %s\n", failedpkgcount, sbuf_data(failedpkgs)); retcode = EPKG_FATAL; } sbuf_delete(failedpkgs); if (messages != NULL) { sbuf_finish(messages); printf("%s", sbuf_data(messages)); } return (retcode == EPKG_OK ? EX_OK : EX_SOFTWARE); }
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); }
int pkg_register_old(struct pkg *pkg) { FILE *fp; char *name, *version, *content, *buf; const char *pkgdbdir, *tmp; char path[MAXPATHLEN]; struct sbuf *install_script = sbuf_new_auto(); struct sbuf *deinstall_script = sbuf_new_auto(); struct pkg_dep *dep = NULL; pkg_to_old(pkg); pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version); pkg_old_emit_content(pkg, &content); pkg_config_string(PKG_CONFIG_DBDIR, &pkgdbdir); snprintf(path, sizeof(path), "%s/%s-%s", pkgdbdir, name, version); mkdir(path, 0755); snprintf(path, sizeof(path), "%s/%s-%s/+CONTENTS", pkgdbdir, name, version); fp = fopen(path, "w"); fputs(content, fp); fclose(fp); pkg_get(pkg, PKG_DESC, &buf); snprintf(path, sizeof(path), "%s/%s-%s/+DESC", pkgdbdir, name, version); fp = fopen(path, "w"); fputs(buf, fp); fclose(fp); pkg_get(pkg, PKG_COMMENT, &buf); snprintf(path, sizeof(path), "%s/%s-%s/+COMMENT", pkgdbdir, name, version); fp = fopen(path, "w"); fprintf(fp, "%s\n", buf); fclose(fp); pkg_get(pkg, PKG_MESSAGE, &buf); if (buf != NULL && *buf != '\0') { snprintf(path, sizeof(path), "%s/%s-%s/+DISPLAY", pkgdbdir, name, version); fp = fopen(path, "w"); fputs(buf, fp); fclose(fp); } sbuf_clear(install_script); tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_INSTALL); if (tmp != NULL && *tmp != '\0') { if (sbuf_len(install_script) == 0) sbuf_cat(install_script, "#!/bin/sh\n\n"); sbuf_printf(install_script, "if [ \"$2\" = \"PRE-INSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_INSTALL); if (tmp != NULL && *tmp != '\0') { if (sbuf_len(install_script) == 0) sbuf_cat(install_script, "#!/bin/sh\n\n"); sbuf_cat(install_script, tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_INSTALL); if (tmp != NULL && *tmp != '\0') { if (sbuf_len(install_script) == 0) sbuf_cat(install_script, "#!/bin/sh\n\n"); sbuf_printf(install_script, "if [ \"$2\" = \"POST-INSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } if (sbuf_len(install_script) > 0) { sbuf_finish(install_script); snprintf(path, sizeof(path), "%s/%s-%s/+INSTALL", pkgdbdir, name, version); fp = fopen(path, "w"); fputs(sbuf_data(install_script), fp); fclose(fp); } sbuf_clear(deinstall_script); tmp = pkg_script_get(pkg, PKG_SCRIPT_PRE_DEINSTALL); if (tmp != NULL && *tmp != '\0') { if (sbuf_len(deinstall_script) == 0) sbuf_cat(deinstall_script, "#!/bin/sh\n\n"); sbuf_printf(deinstall_script, "if [ \"$2\" = \"DEINSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_DEINSTALL); if (tmp != NULL && *tmp != '\0') { if (sbuf_len(deinstall_script) == 0) sbuf_cat(deinstall_script, "#!/bin/sh\n\n"); sbuf_cat(deinstall_script, tmp); } tmp = pkg_script_get(pkg, PKG_SCRIPT_POST_DEINSTALL); if (tmp != NULL && tmp[0] != '\0') { if (sbuf_len(deinstall_script) == 0) sbuf_cat(deinstall_script, "#!/bin/sh\n\n"); sbuf_printf(deinstall_script, "if [ \"$2\" = \"POST-DEINSTALL\" ]; then\n" "%s\n" "fi\n", tmp); } if (sbuf_len(deinstall_script) > 0) { sbuf_finish(deinstall_script); snprintf(path, sizeof(path), "%s/%s-%s/+DEINSTALL", pkgdbdir, name, version); fp = fopen(path, "w"); fputs(sbuf_data(deinstall_script), fp); fclose(fp); } while (pkg_deps(pkg, &dep)) { snprintf(path, sizeof(path), "%s/%s-%s/+REQUIRED_BY", pkgdbdir, pkg_dep_name(dep), pkg_dep_version(dep)); fp = fopen(path, "a"); fprintf(fp, "%s-%s\n", name, version); fclose(fp); } return (EPKG_OK); }