Пример #1
0
static int
pkg_repo_binary_create_symlink(struct pkg *pkg, const char *fname,
	const char *dir)
{
	const char *ext, *dest_fname;
	char link_dest_tmp[MAXPATHLEN], link_dest[MAXPATHLEN];

	/* Create symlink from full pkgname */
	ext = strrchr(fname, '.');
	pkg_snprintf(link_dest, sizeof(link_dest), "%S/%n-%v%S",
		dir, pkg, pkg, ext ? ext : "");
	snprintf(link_dest_tmp, sizeof(link_dest_tmp), "%s.new", link_dest);

	/* Ignore errors here */
	(void)unlink(link_dest_tmp);

	/* Trim the path to just the filename. */
	if ((dest_fname = strrchr(fname, '/')) != NULL)
		++dest_fname;
	if (symlink(dest_fname, link_dest_tmp) == -1) {
		pkg_emit_errno("symlink", link_dest);
		return (EPKG_FATAL);
	}

	if (rename(link_dest_tmp, link_dest) == -1) {
		pkg_emit_errno("rename", link_dest);
		unlink(link_dest_tmp);
		return (EPKG_FATAL);
	}

	return (EPKG_OK);
}
Пример #2
0
int
pkg_repo_binary_get_cached_name(struct pkg_repo *repo, struct pkg *pkg,
	char *dest, size_t destlen)
{
	const char *ext = NULL;
	const char *cachedir = NULL;
	const char *packagesite;
	struct stat st;

	cachedir = pkg_object_string(pkg_config_get("PKG_CACHEDIR"));

	packagesite = pkg_repo_url(repo);

	if (strncmp(packagesite, "file://", 7) == 0) {
		snprintf(dest, destlen, "%s/%s", packagesite + 7,
		    pkg->repopath);
		return (EPKG_OK);
	}

	if (pkg->repopath != NULL)
		ext = strrchr(pkg->repopath, '.');

	if (ext != NULL) {
		/*
		 * The real naming scheme:
		 * <cachedir>/<name>-<version>-<checksum>.txz
		 */
		pkg_snprintf(dest, destlen, "%S/%n-%v-%z%S",
				cachedir, pkg, pkg, pkg, ext);
		if (stat (dest, &st) == -1 || pkg->pkgsize != st.st_size)
			return (EPKG_FATAL);

	}
	else {
		pkg_snprintf(dest, destlen, "%S/%n-%v-%z",
				cachedir, pkg, pkg, pkg);
	}

	return (EPKG_OK);
}
Пример #3
0
void
pkg_repo_binary_get_cached_name(struct pkg_repo *repo, struct pkg *pkg,
	char *dest, size_t destlen)
{
	const char *sum, *name, *version, *repourl, *ext = NULL;
	const char *cachedir = NULL;
	struct stat st;

	cachedir = pkg_object_string(pkg_config_get("PKG_CACHEDIR"));

	pkg_get(pkg, PKG_CKSUM, &sum, PKG_NAME, &name, PKG_VERSION, &version,
			PKG_REPOPATH, &repourl);

	if (repourl != NULL)
		ext = strrchr(repourl, '.');

	if (ext != NULL) {
		/*
		 * XXX:
		 * This code tries to skip refetching but it should be removed as soon
		 * as we transfer to new scheme.
		 */
		pkg_snprintf(dest, destlen, "%S/%n-%v-%z",
				cachedir, pkg, pkg, pkg);
		if (stat (dest, &st) != -1)
			return;

		/*
		 * The real naming scheme:
		 * <cachedir>/<name>-<version>-<checksum>.txz
		 */
		pkg_snprintf(dest, destlen, "%S/%n-%v-%z%S",
				cachedir, pkg, pkg, pkg, ext);
	}
	else {
		pkg_snprintf(dest, destlen, "%S/%n-%v-%z",
				cachedir, pkg, pkg, pkg);
	}
}
Пример #4
0
void
print_jobs_summary(struct pkg_jobs *jobs, const char *msg, ...)
{
	struct pkg *pkg = NULL;
	char path[MAXPATHLEN];
	struct stat st;
	const char *oldversion, *cachedir, *why;
	int64_t dlsize, oldsize, newsize;
	int64_t flatsize, oldflatsize, pkgsize;
	char size[7];
	va_list ap;
	pkg_jobs_t type;

	type = pkg_jobs_type(jobs);

	va_start(ap, msg);
	vprintf(msg, ap);
	va_end(ap);

	dlsize = oldsize = newsize = 0;
	flatsize = oldflatsize = pkgsize = 0;
	oldversion = NULL;
	
	pkg_config_string(PKG_CONFIG_CACHEDIR, &cachedir);

	while (pkg_jobs(jobs, &pkg) == EPKG_OK) {
		pkg_get(pkg, PKG_OLD_VERSION, &oldversion,
		    PKG_FLATSIZE, &flatsize, PKG_OLD_FLATSIZE, &oldflatsize,
		    PKG_PKGSIZE, &pkgsize, PKG_REASON, &why);

		if (pkg_is_locked(pkg)) {
			pkg_printf("\tPackage %n-%v is locked ", pkg, pkg);
			switch (type) {
			case PKG_JOBS_INSTALL:
			case PKG_JOBS_UPGRADE:
				/* If it's a new install, then it
				 * cannot have been locked yet. */
				if (oldversion != NULL) {
					switch(pkg_version_change(pkg)) {
					case PKG_UPGRADE:
						pkg_printf("and may not be upgraded to version %v\n", pkg);
						break;
					case PKG_REINSTALL:
						printf("and may not be reinstalled\n");
						break;
					case PKG_DOWNGRADE:
						pkg_printf("and may not be downgraded to version %v\n", pkg);
						break;
					}
					continue;
				} 
				break;
			case PKG_JOBS_DEINSTALL:
			case PKG_JOBS_AUTOREMOVE:
				printf("and may not be deinstalled\n");
				continue;
				break;
			case PKG_JOBS_FETCH:
				printf("but a new package can still be fetched\n");
				break;
			}

		}

		switch (type) {
		case PKG_JOBS_INSTALL:
		case PKG_JOBS_UPGRADE:
			pkg_snprintf(path, MAXPATHLEN, "%S/%R", cachedir, pkg);

			if (stat(path, &st) == -1 || pkgsize != st.st_size)
				/* file looks corrupted (wrong size),
				   assume a checksum mismatch will
				   occur later and the file will be
				   fetched from remote again */

				dlsize += pkgsize;

			if (oldversion != NULL) {
				switch (pkg_version_change(pkg)) {
				case PKG_DOWNGRADE:
					pkg_printf("\tDowngrading %n: %V -> %v", pkg, pkg, pkg);
					if (pkg_repos_count() > 1)
						pkg_printf(" [%N]", pkg);
					printf("\n");
					break;
				case PKG_REINSTALL:
					pkg_printf("\tReinstalling %n-%v", pkg, pkg);
					if (pkg_repos_count() > 1)
						pkg_printf(" [%N]", pkg);
					if (why != NULL)
						printf(" (%s)", why);
					printf("\n");
					break;
				case PKG_UPGRADE:
					pkg_printf("\tUpgrading %n: %V -> %v", pkg, pkg, pkg);
					if (pkg_repos_count() > 1)
						pkg_printf(" [%N]", pkg);
					printf("\n");
					break;
				}
				oldsize += oldflatsize;
				newsize += flatsize;
			} else {
				newsize += flatsize;

				pkg_printf("\tInstalling %n: %v", pkg, pkg);
				if (pkg_repos_count() > 1)
					pkg_printf(" [%N]", pkg);
				printf("\n");
			}
			break;
		case PKG_JOBS_DEINSTALL:
		case PKG_JOBS_AUTOREMOVE:
			oldsize += oldflatsize;
			newsize += flatsize;
			
			pkg_printf("\t%n-%v\n", pkg, pkg);
			break;
		case PKG_JOBS_FETCH:
			dlsize += pkgsize;
			pkg_snprintf(path, MAXPATHLEN, "%S/%R", cachedir, pkg);
			if (stat(path, &st) != -1)
				oldsize = st.st_size;
			else
				oldsize = 0;
			dlsize -= oldsize;

			humanize_number(size, sizeof(size), pkgsize, "B", HN_AUTOSCALE, 0);

			pkg_printf("\t%n-%v ", pkg, pkg);
			printf("(%" PRId64 "%% of %s)\n", 100 - (100 * oldsize)/pkgsize, size);
			break;
		}
	}

	if (oldsize > newsize) {
		humanize_number(size, sizeof(size), oldsize - newsize, "B", HN_AUTOSCALE, 0);

		switch (type) {
		case PKG_JOBS_INSTALL:
			printf("\nThe installation will free %s\n", size);
			break;
		case PKG_JOBS_UPGRADE:
			printf("\nThe upgrade will free %s\n", size);
			break;
		case PKG_JOBS_DEINSTALL:
		case PKG_JOBS_AUTOREMOVE:
			printf("\nThe deinstallation will free %s\n", size);
			break;
		case PKG_JOBS_FETCH:
			/* nothing to report here */
			break;
		}
	} else if (newsize > oldsize) {
		humanize_number(size, sizeof(size), newsize - oldsize, "B", HN_AUTOSCALE, 0);

		switch (type) {
		case PKG_JOBS_INSTALL:
			printf("\nThe installation will require %s more space\n", size);
			break;
		case PKG_JOBS_UPGRADE:
			printf("\nThe upgrade will require %s more space\n", size);
			break;
		case PKG_JOBS_DEINSTALL:
		case PKG_JOBS_AUTOREMOVE:
			printf("\nThe deinstallation will require %s more space\n", size);
			break;
		case PKG_JOBS_FETCH:
			/* nothing to report here */
			break;
		}
	}

	if ((type == PKG_JOBS_INSTALL) || (type == PKG_JOBS_FETCH) || (type == PKG_JOBS_UPGRADE)) {
		humanize_number(size, sizeof(size), dlsize, "B", HN_AUTOSCALE, 0);
		printf("\n%s to be downloaded\n", size);
	}
}
Пример #5
0
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);
}
Пример #6
0
static int
pkg_repo_binary_try_fetch(struct pkg_repo *repo, struct pkg *pkg,
	bool already_tried, bool mirror, const char *destdir)
{
	char dest[MAXPATHLEN];
	char url[MAXPATHLEN];
	char *dir = NULL;
	bool fetched = false;
	struct stat st;
	char *path = NULL;
	const char *packagesite = NULL;
	ssize_t offset = -1;

	int retcode = EPKG_OK;

	assert((pkg->type & PKG_REMOTE) == PKG_REMOTE);

	if (mirror) {
		const char *cachedir;

		if (destdir != NULL)
			cachedir = destdir;
		else
			cachedir = pkg_object_string(pkg_config_get("PKG_CACHEDIR"));

		snprintf(dest, sizeof(dest), "%s/%s", cachedir, pkg->repopath);
	}
	else
		pkg_repo_binary_get_cached_name(repo, pkg, dest, sizeof(dest));

	/* If it is already in the local cachedir, dont bother to
	 * download it */
	if (stat(dest, &st) == 0) {
		/* try to resume */
		if (pkg->pkgsize > st.st_size) {
			offset = st.st_size;
			pkg_debug(1, "Resuming fetch");
		} else {
			goto checksum;
		}
	}

	/* Create the dirs in cachedir */
	dir = strdup(dest);
	if (dir == NULL || (path = dirname(dir)) == NULL) {
		pkg_emit_errno("dirname", dest);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if ((retcode = mkdirs(path)) != EPKG_OK)
		goto cleanup;

	/*
	 * In multi-repos the remote URL is stored in pkg[PKG_REPOURL]
	 * For a single attached database the repository URL should be
	 * defined by URL.
	 */
	packagesite = pkg_repo_url(repo);

	if (packagesite == NULL || packagesite[0] == '\0') {
		pkg_emit_error("URL is not defined");
		retcode = 1;
		goto cleanup;
	}

	if (packagesite[strlen(packagesite) - 1] == '/')
		pkg_snprintf(url, sizeof(url), "%S%R", packagesite, pkg);
	else
		pkg_snprintf(url, sizeof(url), "%S/%R", packagesite, pkg);

	if (!mirror && strncasecmp(packagesite, "file://", 7) == 0) {
		free(dir);
		return (EPKG_OK);
	}

	retcode = pkg_fetch_file(repo, url, dest, 0, offset, pkg->pkgsize);
	fetched = true;

	if (retcode != EPKG_OK)
		goto cleanup;

checksum:
	/*	checksum calculation is expensive, if size does not
		match, skip it and assume failed checksum. */
	if (stat(dest, &st) == -1 || pkg->pkgsize != st.st_size) {
		if (already_tried) {
			pkg_emit_error("cached package %s-%s: "
			    "size mismatch, cannot continue",
			    pkg->name, pkg->version);
			retcode = EPKG_FATAL;
			goto cleanup;
		}

		unlink(dest);
		free(dir);
		pkg_emit_error("cached package %s-%s: "
		    "size mismatch, fetching from remote",
		    pkg->name, pkg->version);
		return (pkg_repo_binary_try_fetch(repo, pkg, true, mirror, destdir));
	}
	if (pkg_checksum_validate_file(dest, pkg->sum) != 0) {
		if (already_tried || fetched) {
			pkg_emit_error("%s-%s failed checksum "
			    "from repository", pkg->name, pkg->version);
			retcode = EPKG_FATAL;
		} else {
			pkg_emit_error("cached package %s-%s: "
			    "checksum mismatch, fetching from remote",
			    pkg->name, pkg->version);
			unlink(dest);
			return (pkg_repo_binary_try_fetch(repo, pkg, true, mirror, destdir));
		}
	}

cleanup:

	if (retcode != EPKG_OK)
		unlink(dest);
	else if (!mirror && path != NULL) {
		(void)pkg_repo_binary_create_symlink(pkg, dest, path);
	}

	/* allowed even if dir is NULL */
	free(dir);

	return (retcode);
}
Пример #7
0
Файл: create.c Проект: brd/pkgng
static int
pkg_create_matches(int argc, char **argv, match_t match, pkg_formats fmt,
    const char * const outdir, bool overwrite)
{
	int i, ret = EPKG_OK, retcode = EPKG_OK;
	struct pkg *pkg = NULL;
	struct pkgdb *db = NULL;
	struct pkgdb_it *it = NULL;
	int query_flags = PKG_LOAD_DEPS | PKG_LOAD_FILES |
	    PKG_LOAD_CATEGORIES | PKG_LOAD_DIRS | PKG_LOAD_SCRIPTS |
	    PKG_LOAD_OPTIONS | PKG_LOAD_LICENSES |
	    PKG_LOAD_USERS | PKG_LOAD_GROUPS | PKG_LOAD_SHLIBS_REQUIRED |
	    PKG_LOAD_PROVIDES | PKG_LOAD_REQUIRES |
	    PKG_LOAD_SHLIBS_PROVIDED | PKG_LOAD_ANNOTATIONS;
	struct pkg_entry *e = NULL, *etmp;
	char pkgpath[MAXPATHLEN];
	const char *format = NULL;
	bool foundone;

	if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
		pkgdb_close(db);
		return (EX_IOERR);
	}
	/* XXX: get rid of hardcoded timeouts */
	if (pkgdb_obtain_lock(db, PKGDB_LOCK_READONLY) != EPKG_OK) {
		pkgdb_close(db);
		warnx("Cannot get a read lock on a database, it is locked by another process");
		return (EX_TEMPFAIL);
	}

	switch (fmt) {
	case TXZ:
		format = "txz";
		break;
	case TBZ:
		format = "tbz";
		break;
	case TGZ:
		format = "tgz";
		break;
	case TAR:
		format = "tar";
		break;
	}

	for (i = 0; i < argc || match == MATCH_ALL; i++) {
		if (match == MATCH_ALL) {
			printf("Loading the package list...\n");
			if ((it = pkgdb_query(db, NULL, match)) == NULL)
				goto cleanup;
			match = !MATCH_ALL;
		} else
			if ((it = pkgdb_query(db, argv[i], match)) == NULL)
				goto cleanup;

		foundone = false;
		while ((ret = pkgdb_it_next(it, &pkg, query_flags)) == EPKG_OK) {
			if ((e = malloc(sizeof(struct pkg_entry))) == NULL)
				err(1, "malloc(pkg_entry)");
			e->pkg = pkg;
			pkg = NULL;
			DL_APPEND(pkg_head, e);
			foundone = true;
		}
		if (!foundone) {
			warnx("No installed package matching \"%s\" found\n",
			    argv[i]);
			retcode++;
		}

		pkgdb_it_free(it);
		if (ret != EPKG_END)
			retcode++;
	}

	DL_FOREACH_SAFE(pkg_head, e, etmp) {
		DL_DELETE(pkg_head, e);

		if (!overwrite) {
			pkg_snprintf(pkgpath, sizeof(pkgpath), "%S/%n-%v.%S",
			    outdir, e->pkg, e->pkg, format);
			if (access(pkgpath, F_OK) == 0) {
				pkg_printf("%n-%v already packaged, skipping...\n",
				    e->pkg, e->pkg);
				pkg_free(e->pkg);
				free(e);
				continue;
			}
		}
		pkg_printf("Creating package for %n-%v\n", e->pkg, e->pkg);
		if (pkg_create_installed(outdir, fmt, e->pkg) !=
		    EPKG_OK)
			retcode++;
		pkg_free(e->pkg);
		free(e);
	}
Пример #8
0
/* ---------------------------------------------------------------------
 */
int
netsnmp_swinst_arch_load( netsnmp_container *container, u_int flags)
{
    DIR                  *d;
    struct dirent        *dp;
    struct stat           stat_buf;
#ifdef HAVE_PKGINFO
    char                 *v, *c;
#endif
    char                  buf[ BUFSIZ ];
    unsigned char        *cp;
    time_t                install_time;
    size_t                date_len;
    int                   i = 1;
    netsnmp_swinst_entry *entry;
#ifdef HAVE_LIBPKG
    struct pkgdb *db = NULL;
    struct pkgdb_it *it = NULL;
    struct pkg *pkg = NULL;
    char pkgname[ SNMP_MAXPATH ];
    char pkgdate[ BUFSIZ ];
    int pkgng = 0;

    if (pkg_init(NULL, NULL)) {
        snmp_log( LOG_ERR, "SWInst: error initializing pkgng db\n" );
        return 1;
    }

    if (pkgdb_open(&db, PKGDB_DEFAULT) != EPKG_OK) {
	snmp_log( LOG_ERR, "SWInst: error opening pkgng db\n" );
	return 1;
    }

    if (pkg_status(NULL) == PKG_STATUS_ACTIVE) {
	pkgng = 1;
    } else {
	snmp_log( LOG_INFO, "SWInst: not a pkgng system\n" );
    }

    /* if we are using FreeBSD's pkgng */
    if (pkgng) {
        if ((it = pkgdb_query(db, NULL, MATCH_ALL)) == NULL) {
            snmp_log( LOG_ERR, "SWInst: error querying pkgng db\n" );
            return 1;
        }

        while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) {
            pkg_snprintf(pkgname, sizeof(pkgname), "%n-%v", pkg, pkg);
            pkg_snprintf(pkgdate, sizeof(pkgdate), "%t", pkg);

            entry = netsnmp_swinst_entry_create( i++ );

            if (NULL == entry)
                continue;   /* error already logged by function */

            CONTAINER_INSERT(container, entry);

            entry->swName_len = snprintf( entry->swName, sizeof(entry->swName),
                                          "%s", pkgname );
            if (entry->swName_len >= sizeof(entry->swName))
                entry->swName_len = sizeof(entry->swName)-1;

            install_time = atoi(pkgdate);
            cp = date_n_time( &install_time, &date_len );
            memcpy( entry->swDate, cp, date_len );
            entry->swDate_len = date_len;
        }

        pkgdb_it_free(it);
        pkgdb_close(db);
        pkg_shutdown();
    } else {
#endif /* HAVE_LIBPKG */
        if ( !pkg_directory[0] ) {
            return 1;    /* Can't report installed packages
                         if there isn't a list of them! */
        }

        d = opendir( pkg_directory );
        if (!d)
            return 1;

        while ((dp = readdir(d)) != NULL) {
            if ( '.' == dp->d_name[0] )
                continue;
            snprintf( buf, BUFSIZ, "%s/%s", pkg_directory, dp->d_name );
            if (stat( buf, &stat_buf ) < 0)
                continue;
            entry = netsnmp_swinst_entry_create( i++ );
            if (NULL == entry)
                continue;   /* error already logged by function */
            CONTAINER_INSERT(container, entry);

#ifdef HAVE_PKGINFO
	    v = pkgparam( dp->d_name, "VERSION" );
	    c = pkgparam( dp->d_name, "CATEGORY" );

	    entry->swName_len = snprintf( entry->swName, sizeof(entry->swName),
					  "%s-%s", dp->d_name, v );
	    if (entry->swName_len >= sizeof(entry->swName))
		entry->swName_len = sizeof(entry->swName)-1;
	    entry->swType = (NULL != strstr( c, "system"))
			    ? 2      /* operatingSystem */
			    : 4;     /*  application    */

	    /* Do we need to free 'v' & 'c' ??? */
#else
	    entry->swName_len = snprintf( entry->swName, sizeof(entry->swName),
					  "%s", dp->d_name );
	    if (entry->swName_len >= sizeof(entry->swName))
		entry->swName_len = sizeof(entry->swName)-1;

	    /* no information about O/S vs application packages ??? */
#endif

	    install_time = stat_buf.st_mtime;
	    cp = date_n_time( &install_time, &date_len );
	    memcpy( entry->swDate, cp, date_len );
	    entry->swDate_len = date_len;
	}
	closedir( d );
#ifdef HAVE_LIBPKG
    }
#endif

    DEBUGMSGTL(("swinst:load:arch"," loaded %d entries\n",
                (int)CONTAINER_SIZE(container)));

    return 0;
}
Пример #9
0
static
int do_load(struct pkgdir *pkgdir, unsigned ldflags)
{
    struct pndir       *idx;
    struct pkg         *pkg = NULL;
    struct pkg_offs    pkgo;
    struct pkg_data    *pkgd;
    struct tndb_it     it;
    tn_stream          *st;
    tn_array           *ign_patterns = NULL;
    int                rc, klen, vlen, nerr = 0;
    char               key[TNDB_KEY_MAX + 1], path[PATH_MAX];

    idx = pkgdir->mod_data;
    if (!tndb_it_start(idx->db, &it))
        return 0;

    vf_url_slim(path, sizeof(path), pkgdir->idxpath, 0);
    
    if ((ldflags & PKGDIR_LD_DOIGNORE) && pkgdir->src &&
        n_array_size(pkgdir->src->ign_patterns)) {
        ign_patterns = pkgdir->src->ign_patterns;
    }

    DBGF("ign_patterns %p\n", ign_patterns);
    
    st = tndb_it_stream(&it);
    while ((rc = tndb_it_get_begin(&it, key, &klen, &vlen)) > 0) {
        struct pkg kpkg;
        
        n_assert(klen > 0);
            
        if (*key == '%' && strncmp(key, "%__h_", 5) == 0)
            goto l_continue_loop;
        
        if (pndir_parse_pkgkey(key, klen, &kpkg) == NULL) {
            logn(LOGERR, "%s: parse error", key);
            nerr++;
            goto l_continue_loop;
        }
        
        if (ign_patterns) {
            char buf[512];
            unsigned int i;
            pkg_snprintf(buf, sizeof(buf), &kpkg);
            for (i=0; i < n_array_size(ign_patterns); i++) {
                char *p = n_array_nth(ign_patterns, i);
                if (fnmatch(p, buf, 0) == 0) {
                    msgn(3, "pndir: ignored %s", pkg_snprintf_s(pkg));
                    goto l_continue_loop;
                }
            }
        }

        pkg = pkg_restore_st(st, pkgdir->na, &kpkg, pkgdir->foreign_depdirs,
                             ldflags, &pkgo, path);

        DBGF("%s -> %p\n", pkg_snprintf_s(&kpkg), pkg);
        if (pkg == NULL) {
            nerr++;
            goto l_continue_loop;
        }
        
        pkg->pkgdir = pkgdir;

        pkgd = pkg_data_malloc(pkgdir->na);
        pkgd->off_nodep_files = pkgo.nodep_files_offs;
        //pkgd->off_pkguinf = pkgo.pkguinf_offs;
        pkgd->db = tndb_ref(idx->db);
            
        if (idx->db_dscr_h)
            pkgd->db_dscr_h = n_ref(idx->db_dscr_h);
        
        if (pkgdir->langs)
            pkgd->langs = n_ref(pkgdir->langs);
        
        pkg->pkgdir_data = pkgd;
        pkg->pkgdir_data_free = pkg_data_free;
        pkg->load_pkguinf = pndir_m_load_pkguinf;
        pkg->load_nodep_fl = pndir_load_nodep_fl;
        n_array_push(pkgdir->pkgs, pkg);

    l_continue_loop:
        if (!tndb_it_get_end(&it) || nerr > 0) {
            logn(LOGERR, "%s: broken file", path);
            nerr++;
            break;
        }
    }
    
    if (nerr)
        n_array_clean(pkgdir->pkgs);
        
    return n_array_size(pkgdir->pkgs);
}
Пример #10
0
static void
print_jobs_summary_pkg(struct pkg *pkg, pkg_jobs_t type, int64_t *oldsize,
		int64_t *newsize, int64_t *dlsize)
{
	const char *oldversion, *cachedir, *why;
	char path[MAXPATHLEN];
	struct stat st;
	int64_t flatsize, oldflatsize, pkgsize;
	char size[7];

	flatsize = oldflatsize = pkgsize = 0;
	oldversion = NULL;

	pkg_config_string(PKG_CONFIG_CACHEDIR, &cachedir);
	pkg_get(pkg, PKG_OLD_VERSION, &oldversion,
			PKG_FLATSIZE, &flatsize, PKG_OLD_FLATSIZE, &oldflatsize,
			PKG_PKGSIZE, &pkgsize, PKG_REASON, &why);

	if (pkg_is_locked(pkg)) {
		pkg_printf("\tPackage %n-%v is locked ", pkg, pkg);
		switch (type) {
		case PKG_JOBS_INSTALL:
		case PKG_JOBS_UPGRADE:
			/* If it's a new install, then it
			 * cannot have been locked yet. */
			if (oldversion != NULL) {
				switch(pkg_version_change(pkg)) {
				case PKG_UPGRADE:
					pkg_printf("and may not be upgraded to version %v\n", pkg);
					break;
				case PKG_REINSTALL:
					printf("and may not be reinstalled\n");
					break;
				case PKG_DOWNGRADE:
					pkg_printf("and may not be downgraded to version %v\n", pkg);
					break;
				}
				return;
			}
			break;
		case PKG_JOBS_DEINSTALL:
		case PKG_JOBS_AUTOREMOVE:
			printf("and may not be deinstalled\n");
			return;
			break;
		case PKG_JOBS_FETCH:
			printf("but a new package can still be fetched\n");
			break;
		}

	}

	switch (type) {
	case PKG_JOBS_INSTALL:
	case PKG_JOBS_UPGRADE:
		pkg_snprintf(path, MAXPATHLEN, "%S/%R", cachedir, pkg);

		if (stat(path, &st) == -1 || pkgsize != st.st_size)
			/* file looks corrupted (wrong size),
					   assume a checksum mismatch will
					   occur later and the file will be
					   fetched from remote again */

			*dlsize += pkgsize;

		if (oldversion != NULL) {
			switch (pkg_version_change(pkg)) {
			case PKG_DOWNGRADE:
				pkg_printf("\tDowngrading %n: %V -> %v", pkg, pkg, pkg);
				if (pkg_repos_total_count() > 1)
					pkg_printf(" [%N]", pkg);
				printf("\n");
				break;
			case PKG_REINSTALL:
				pkg_printf("\tReinstalling %n-%v", pkg, pkg);
				if (pkg_repos_total_count() > 1)
					pkg_printf(" [%N]", pkg);
				if (why != NULL)
					printf(" (%s)", why);
				printf("\n");
				break;
			case PKG_UPGRADE:
				pkg_printf("\tUpgrading %n: %V -> %v", pkg, pkg, pkg);
				if (pkg_repos_total_count() > 1)
					pkg_printf(" [%N]", pkg);
				printf("\n");
				break;
			}
			*oldsize += oldflatsize;
			*newsize += flatsize;
		} else {
			*newsize += flatsize;

			pkg_printf("\tInstalling %n: %v", pkg, pkg);
			if (pkg_repos_total_count() > 1)
				pkg_printf(" [%N]", pkg);
			printf("\n");
		}
		break;
	case PKG_JOBS_DEINSTALL:
	case PKG_JOBS_AUTOREMOVE:
		*oldsize += oldflatsize;
		*newsize += flatsize;

		pkg_printf("\tRemoving %n-%v\n", pkg, pkg);
		break;
	case PKG_JOBS_FETCH:
		*dlsize += pkgsize;
		pkg_snprintf(path, MAXPATHLEN, "%S/%R", cachedir, pkg);
		if (stat(path, &st) != -1)
			*oldsize = st.st_size;
		else
			*oldsize = 0;
		*dlsize -= *oldsize;

		humanize_number(size, sizeof(size), pkgsize, "B", HN_AUTOSCALE, 0);

		pkg_printf("\t%n-%v ", pkg, pkg);
		printf("(%" PRId64 "%% of %s)\n", 100 - (100 * (*oldsize))/pkgsize, size);
		break;
	}
}
Пример #11
0
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;
	bool		 developer;
	struct stat	 st;
	char		 sha256[SHA256_DIGEST_LENGTH * 2 + 1];
	int64_t		 flatsize = 0;
	const char	*relocation;
	struct hardlinks *hardlinks = NULL;

	if (pkg_is_valid(pkg) != EPKG_OK) {
		pkg_emit_error("the package is not valid");
		return (EPKG_FATAL);
	}

	relocation = pkg_kv_get(&pkg->annotations, "relocated");
	if (relocation == NULL)
		relocation = "";

	/*
	 * Get / compute size / checksum if not provided in the manifest
	 */
	while (pkg_files(pkg, &file) == EPKG_OK) {

		snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "",
		    relocation, file->path);

		if (lstat(fpath, &st) == -1) {
			pkg_emit_error("file '%s' is missing", fpath);
			return (EPKG_FATAL);
		}

		if (file->size == 0)
			file->size = (int64_t)st.st_size;

		if (st.st_nlink == 1 || !check_for_hardlink(&hardlinks, &st)) {
			flatsize += file->size;
		}

		if (S_ISLNK(st.st_mode)) {

			if (file->sum[0] == '\0') {
				if (pkg_symlink_cksum(fpath, root, sha256) == EPKG_OK)
					strlcpy(file->sum, sha256, sizeof(file->sum));
				else
					return (EPKG_FATAL);
			}
		}
		else {
			if (file->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->flatsize = flatsize;
	HASH_FREE(hardlinks, free);

	if (pkg->type == PKG_OLD_FILE) {
		char oldcomment[BUFSIZ];

		pkg_old_emit_content(pkg, &m);
		packing_append_buffer(pkg_archive, m, "+CONTENTS", strlen(m));
		free(m);

		packing_append_buffer(pkg_archive, pkg->desc, "+DESC", strlen(pkg->desc));
		packing_append_buffer(pkg_archive, pkg->message, "+DISPLAY", strlen(pkg->message));
		pkg_snprintf(oldcomment, sizeof(oldcomment), "%c\n", pkg);
		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_analyse_files(NULL, 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);
	}

	while (pkg_files(pkg, &file) == EPKG_OK) {

		snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "",
		    relocation, file->path);

		ret = packing_append_file_attr(pkg_archive, fpath, file->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) {
		snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "",
		    relocation, dir->path);

		ret = packing_append_file_attr(pkg_archive, fpath, dir->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);
}
Пример #12
0
static int
pkg_repo_binary_try_fetch(struct pkg_repo *repo, struct pkg *pkg,
	bool already_tried, bool mirror, const char *destdir)
{
	char dest[MAXPATHLEN];
	char url[MAXPATHLEN];
	char *dir = NULL;
	int fetched = 0;
	char cksum[SHA256_DIGEST_LENGTH * 2 +1];
	int64_t pkgsize;
	struct stat st;
	char *path = NULL;
	const char *packagesite = NULL, *repourl;

	int retcode = EPKG_OK;
	const char *name, *version, *sum;

	assert((pkg->type & PKG_REMOTE) == PKG_REMOTE);

	pkg_get(pkg, PKG_CKSUM, &sum,
			PKG_NAME, &name, PKG_VERSION, &version, PKG_PKGSIZE, &pkgsize,
			PKG_REPOPATH, &repourl);

	if (mirror) {
		const char *cachedir;

		if (destdir != NULL)
			cachedir = destdir;
		else
			cachedir = pkg_object_string(pkg_config_get("PKG_CACHEDIR"));

		snprintf(dest, sizeof(dest), "%s/%s",
						cachedir, repourl);
	}
	else
		pkg_repo_binary_get_cached_name(repo, pkg, dest, sizeof(dest));

	/* If it is already in the local cachedir, dont bother to
	 * download it */
	if (access(dest, F_OK) == 0)
		goto checksum;

	/* Create the dirs in cachedir */
	dir = strdup(dest);
	if (dir == NULL || (path = dirname(dir)) == NULL) {
		pkg_emit_errno("dirname", dest);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if ((retcode = mkdirs(path)) != EPKG_OK)
		goto cleanup;

	/*
	 * In multi-repos the remote URL is stored in pkg[PKG_REPOURL]
	 * For a single attached database the repository URL should be
	 * defined by PACKAGESITE.
	 */
	packagesite = pkg_repo_url(repo);

	if (packagesite == NULL || packagesite[0] == '\0') {
		pkg_emit_error("PACKAGESITE is not defined");
		retcode = 1;
		goto cleanup;
	}

	if (packagesite[strlen(packagesite) - 1] == '/')
		pkg_snprintf(url, sizeof(url), "%S%R", packagesite, pkg);
	else
		pkg_snprintf(url, sizeof(url), "%S/%R", packagesite, pkg);

	if (!mirror && strncasecmp(packagesite, "file://", 7) == 0) {
		pkg_set(pkg, PKG_REPOPATH, url + 7);
		return (EPKG_OK);
	}

	retcode = pkg_fetch_file(repo, url, dest, 0);
	fetched = 1;

	if (retcode != EPKG_OK)
		goto cleanup;

checksum:
	/*	checksum calculation is expensive, if size does not
		match, skip it and assume failed checksum. */
	if (stat(dest, &st) == -1 || pkgsize != st.st_size) {
		if (already_tried) {
			pkg_emit_error("cached package %s-%s: "
				"size mismatch, cannot continue",
				name, version);
			retcode = EPKG_FATAL;
			goto cleanup;
		}

		unlink(dest);
		pkg_emit_error("cached package %s-%s: "
			"size mismatch, fetching from remote",
			name, version);
		return (pkg_repo_binary_try_fetch(repo, pkg, true, mirror, destdir));
	}
	retcode = sha256_file(dest, cksum);
	if (retcode == EPKG_OK) {
		if (strcmp(cksum, sum)) {
			if (already_tried || fetched == 1) {
				pkg_emit_error("%s-%s failed checksum "
				    "from repository", name, version);
				retcode = EPKG_FATAL;
			} else {
				pkg_emit_error("cached package %s-%s: "
				    "checksum mismatch, fetching from remote",
				    name, version);
				unlink(dest);
				return (pkg_repo_binary_try_fetch(repo, pkg, true, mirror, destdir));
			}
		}
	}

cleanup:

	if (retcode != EPKG_OK)
		unlink(dest);
	else if (!mirror && path != NULL) {
		(void)pkg_repo_binary_create_symlink(pkg, dest, path);
	}

	/* allowed even if dir is NULL */
	free(dir);

	return (retcode);
}
Пример #13
0
int
pkg_repo_fetch(struct pkg *pkg)
{
	char dest[MAXPATHLEN + 1];
	char url[MAXPATHLEN + 1];
	int fetched = 0;
	char cksum[SHA256_DIGEST_LENGTH * 2 +1];
	char *path = NULL;
	const char *packagesite = NULL;
	const char *cachedir = NULL;
	int retcode = EPKG_OK;
	const char *sum, *name, *version, *reponame;
	struct pkg_repo *repo;

	assert((pkg->type & PKG_REMOTE) == PKG_REMOTE);

	if (pkg_config_string(PKG_CONFIG_CACHEDIR, &cachedir) != EPKG_OK)
		return (EPKG_FATAL);

	pkg_get(pkg, PKG_REPONAME, &reponame,
	    PKG_CKSUM, &sum, PKG_NAME, &name, PKG_VERSION, &version);

	pkg_snprintf(dest, sizeof(dest), "%S/%R", cachedir, pkg);

	/* If it is already in the local cachedir, dont bother to
	 * download it */
	if (access(dest, F_OK) == 0)
		goto checksum;

	/* Create the dirs in cachedir */
	if ((path = dirname(dest)) == NULL) {
		pkg_emit_errno("dirname", dest);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if ((retcode = mkdirs(path)) != EPKG_OK)
		goto cleanup;

	/*
	 * In multi-repos the remote URL is stored in pkg[PKG_REPOURL]
	 * For a single attached database the repository URL should be
	 * defined by PACKAGESITE.
	 */
	repo = pkg_repo_find_name(reponame);
	packagesite = pkg_repo_url(repo);

	if (packagesite == NULL || packagesite[0] == '\0') {
		pkg_emit_error("PACKAGESITE is not defined");
		retcode = 1;
		goto cleanup;
	}

	if (packagesite[strlen(packagesite) - 1] == '/')
		pkg_snprintf(url, sizeof(url), "%S%R", packagesite, pkg);
	else
		pkg_snprintf(url, sizeof(url), "%S/%R", packagesite, pkg);

	retcode = pkg_fetch_file(repo, url, dest, 0);
	fetched = 1;

	if (retcode != EPKG_OK)
		goto cleanup;

	checksum:
	retcode = sha256_file(dest, cksum);
	if (retcode == EPKG_OK)
		if (strcmp(cksum, sum)) {
			if (fetched == 1) {
				pkg_emit_error("%s-%s failed checksum "
				    "from repository", name, version);
				retcode = EPKG_FATAL;
			} else {
				pkg_emit_error("cached package %s-%s: "
				    "checksum mismatch, fetching from remote",
				    name, version);
				unlink(dest);
				return (pkg_repo_fetch(pkg));
			}
		}

	cleanup:
	if (retcode != EPKG_OK)
		unlink(dest);

	return (retcode);
}