PERFORCE change 131990 for review
Garrett Cooper
gcooper at FreeBSD.org
Sat Dec 29 14:07:38 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=131990
Change 131990 by gcooper at shiina-ibook on 2007/12/29 22:06:47
Get rid of a few more todos...
1. Add in $PKG_DIR pluggable support.
2. Get rid of repeated code and toss in a loop.
3. Add .tgz support (yes, .tgz files are valid too!).
Affected files ...
.. //depot/projects/soc2007/revised_fbsd_pkgtools/pkg_revised/v2/contrib/libpkg/pkg_repo_local_freebsd.c#5 edit
Differences ...
==== //depot/projects/soc2007/revised_fbsd_pkgtools/pkg_revised/v2/contrib/libpkg/pkg_repo_local_freebsd.c#5 (text+ko) ====
@@ -28,7 +28,9 @@
#include <sys/param.h>
#include <assert.h>
+#include <errno.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "pkg.h"
@@ -75,48 +77,129 @@
/**
* @brief Retrieves a package from either . or /usr/ports/packages/All/
- * @todo Check if the file we opened is a package. If not try the next file.
- * @todo Make DEFAULT_PKG_DIR pluggable via the $PKG_DIR environment variable.
* @return a package object or NULL
*/
static struct pkg *
file_get_pkg(struct pkg_repo *repo, const char *pkg_name)
{
- char dir[MAXPATHLEN + 1];
+ char pkg_filename[MAXPATHLEN + 1];
+ char *pkg_dir;
struct pkg *pkg;
FILE *fd;
+ int i;
+
assert(repo != NULL);
assert(pkg_name != NULL);
- /*
- * XXX Check the file is a package file after every
- * attempt to open it.
- */
- snprintf(dir, MAXPATHLEN + 1,"%s.tbz", pkg_name);
- fd = fopen(dir, "r");
- if (fd == NULL) {
- snprintf(dir, MAXPATHLEN + 1,
- DEFAULT_PKG_DIR "/All/%s.tbz", pkg_name);
- fd = fopen(dir, "r");
+ /** Grab user defined package directory **/
+ pkg_dir = getenv("PKG_DIR");
+
+ if (pkg_dir == NULL) {
+ pkg_dir = strdup(DEFAULT_PKG_DIR);
}
- if (fd == NULL) {
- fd = fopen(pkg_name, "r");
+
+ if ((MAXPATHLEN+1) <= strlen(pkg_name)) {
+ warnx("Package name length (%d) meets / exceeds"
+ "maximum path length, %d",
+ strlen(pkg_name), (MAXPATHLEN+1));
+ return NULL;
}
- if (fd == NULL) {
- snprintf(dir, MAXPATHLEN + 1,
- DEFAULT_PKG_DIR "/All/%s", pkg_name);
- fd = fopen(dir, "r");
+
+#define NUM_EXTENSIONS 3
+
+ char extensions[NUM_EXTENSIONS][4] = {
+ ".tbz", ".tgz", ""
+ };
+
+ enum pkg_check_iteration {
+ file_localdir_bz2 = 0,
+ file_localdir_gz,
+ file_localdir_no_ext,
+ file_fullpath_bz2,
+ file_fullpath_gz,
+ file_fullpath_no_ext
+ };
+
+ for (i = file_localdir_bz2; i <= file_fullpath_no_ext; i++) {
+
+ /*
+ * Feed back the right set of arguments to test all
+ * possible extension and directory permutations.
+ */
+ snprintf(pkg_filename, MAXPATHLEN + 1, "%s/%s%s%s",
+ ( i < file_localdir_no_ext ? "." : pkg_dir),
+ ( i < file_localdir_no_ext ? "" : "All/" ),
+ pkg_name,
+ extensions[i % NUM_EXTENSIONS]
+ );
+
+ /*
+ * Try opening the file for a read
+ */
+ fd = fopen(pkg_filename, "r");
+
+ /*
+ * Continue on if the file wasn't opened due to a
+ * non-permission related item..
+ */
+ if (fd == NULL && errno != EACCES) {
+ continue;
+ }
+ /*
+ * Can't read the file; bail!
+ */
+ else if (errno == EACCES) {
+ break;
+ }
+ /*
+ * Happy day! File descriptor wasn't null, so let's see if
+ * it's a real package!
+ */
+ else {
+
+ pkg = pkg_new_freebsd_from_file(fd);
+
+ /*
+ * File exists, but according to
+ * pkg_new_freebsd_from_file(..), it wasn't valid. So
+ * just exit the loop..
+ */
+ if (pkg == NULL) {
+
+ /*
+ * fclose(3) failed, so either we have a coding
+ * error somewhere or something nasty is going
+ * on with the FS. Prevent any continued nastiness
+ * from occurring by erroring out.
+ */
+ if (fclose(fd) < 0) {
+ errx("Error encountered when closing "
+ "file. Errno is: %d", ferror(fd));
+ }
+
+ break;
+
+ }
+
+ }
+
}
- if (fd == NULL)
- return NULL;
- pkg = pkg_new_freebsd_from_file(fd);
- if (pkg == NULL) {
- fclose(fd);
- return NULL;
+ /*
+ * Same reasoning as above.
+ */
+ if (fd != NULL && fclose(fd) < 0) {
+ errx("Error encountered when closing file. Errno is: %d",
+ ferror(fd));
}
+ /*
+ * We possibly strdup'ed the string, so attempt to free(2) to avoid memory
+ * leaks. Hopefully glibc won't complain too much about free errors :\..
+ */
+ free(pkg_dir);
return pkg;
+
}
/**
More information about the p4-projects
mailing list