/* * Gets a FILE pointer for a given package name */ static FILE * ftp_get_fd(const char *pkg_name, struct ftp_repo *f_repo) { const char *subdir; const char *fallback_subdir; const char *ext; char *ftpname; FILE *fd; /* * Figure out what order to look for the package */ //if (pkg_in_All(pkg_name)) { subdir = "All"; fallback_subdir = "Latest"; //} else { // subdir = "Latest"; // fallback_subdir = "All"; //} /* Get the extension */ if (pkg_name_has_extension(pkg_name)) ext = ""; else ext = ".tbz"; asprintf(&ftpname, "ftp://%s/%s/%s/%s%s", f_repo->site, f_repo->path, subdir, pkg_name, ext); if (!ftpname) { return NULL; } fd = fetchGetURL(ftpname, "p"); /* Try the alternate subdir if the primary one fails. */ if (fd == NULL) { free(ftpname); asprintf(&ftpname, "ftp://%s/%s/%s/%s%s", f_repo->site, f_repo->path, fallback_subdir, pkg_name, ext); if (!ftpname) { return NULL; } fd = fetchGetURL(ftpname, "p"); if (fd == NULL) { free(ftpname); return NULL; } } free(ftpname); return fd; }
static void gethttpmirrors(struct pkg_repo *repo, const char *url) { FILE *f; char *line = NULL; size_t linecap = 0; ssize_t linelen; struct http_mirror *m; struct url *u; if ((f = fetchGetURL(url, "")) == NULL) return; while ((linelen = getline(&line, &linecap, f)) > 0) { if (strncmp(line, "URL:", 4) == 0) { /* trim '\n' */ if (line[linelen - 1] == '\n') line[linelen - 1 ] = '\0'; line += 4; while (isspace(*line)) { line++; } if (*line == '\0') continue; if ((u = fetchParseURL(line)) != NULL) { m = malloc(sizeof(struct http_mirror)); m->url = u; LL_APPEND(repo->http, m); } } } fclose(f); return; }
FILE * ldif_open_url( LDAP_CONST char *urlstr ) { FILE *url; if( strncasecmp( "file:", urlstr, sizeof("file:")-1 ) == 0 ) { char *p; urlstr += sizeof("file:")-1; /* we don't check for LDAP_DIRSEP since URLs should contain '/' */ if ( urlstr[0] == '/' && urlstr[1] == '/' ) { urlstr += 2; /* path must be absolute if authority is present * technically, file://hostname/path is also legal but we don't * accept a non-empty hostname */ if ( urlstr[0] != '/' ) { #ifdef _WIN32 /* An absolute path in improper file://C:/foo/bar format */ if ( urlstr[1] != ':' ) #endif return NULL; } #ifdef _WIN32 /* An absolute path in proper file:///C:/foo/bar format */ if ( urlstr[2] == ':' ) urlstr++; #endif } p = ber_strdup( urlstr ); /* But we should convert to LDAP_DIRSEP before use */ if ( LDAP_DIRSEP[0] != '/' ) { char *s = p; while (( s = strchr( s, '/' ))) *s++ = LDAP_DIRSEP[0]; } ldap_pvt_hex_unescape( p ); url = fopen( p, "rb" ); ber_memfree( p ); } else { #ifdef HAVE_FETCH url = fetchGetURL( (char*) urlstr, "" ); #else url = NULL; #endif } return url; }
FILE * ldif_open_url( LDAP_CONST char *urlstr ) { FILE *url; if( strncasecmp( "file:", urlstr, sizeof("file:")-1 ) == 0 ) { char *p; urlstr += sizeof("file:")-1; /* we don't check for LDAP_DIRSEP since URLs should contain '/' */ if ( urlstr[0] == '/' && urlstr[1] == '/' ) { urlstr += 2; /* path must be absolute if authority is present */ if ( urlstr[0] != '/' ) return NULL; } p = ber_strdup( urlstr ); /* But we should convert to LDAP_DIRSEP before use */ if ( LDAP_DIRSEP[0] != '/' ) { char *s = p; while (( s = strchr( s, '/' ))) *s++ = LDAP_DIRSEP[0]; } ldap_pvt_hex_unescape( p ); url = fopen( p, "rb" ); ber_memfree( p ); } else { #ifdef HAVE_FETCH url = fetchGetURL( (char*) urlstr, "" ); #else url = NULL; #endif } return url; }
/* * Parse /usr/port/UPDATING for corresponding entries. If no argument is * passed to pkg_updating all entries for all installed ports are displayed. * If a list of portnames is passed to pkg_updating only entries for the * given portnames are displayed. Use the -d option to define that only newer * entries as this date are shown. */ int main(int argc, char *argv[]) { /* Keyword for searching portname in UPDATING. */ const char *affects = "AFFECTS"; /* Indicate a date -> end of a entry. Will fail on 2100-01-01... */ const char *end = "20"; /* Keyword for searching origin portname of installed port. */ const char *origin = "@comment ORIGIN:"; const char *pkgdbpath = LOG_DIR; /* Location of pkgdb */ const char *updatingfile = UPDATING; /* Location of UPDATING */ char *date = NULL; /* Passed -d argument */ char *dateline = NULL; /* Saved date of an entry */ /* Tmp lines for parsing file */ char *tmpline1 = NULL; char *tmpline2 = NULL; char originline[LINE_MAX]; /* Line of +CONTENTS */ /* Temporary variable to create path to +CONTENTS for installed ports. */ char tmp_file[MAXPATHLEN]; char updatingline[LINE_MAX]; /* Line of UPDATING */ int ch; /* Char used by getopt */ int found = 0; /* Found an entry */ int linelength; /* Length of parsed line */ int maxcharperline = LINE_MAX; /* Max chars per line */ int dflag = 0; /* -d option set */ /* If pflag = 0 UPDATING will be checked for all installed ports. */ int pflag = 0; size_t n; /* Offset to create path */ struct dirent *pkgdbdir; /* pkgdb directory */ struct stat attribute; /* attribute of pkgdb element */ /* Needed nodes for linked list with installed ports. */ INSTALLEDPORT *head = (INSTALLEDPORT *) NULL; INSTALLEDPORT *curr = (INSTALLEDPORT *) NULL; DIR *dir; FILE *fd; while ((ch = getopt_long(argc, argv, opts, longopts, NULL)) != -1) { switch (ch) { case 'd': dflag = 1; date = optarg; break; case 'f': updatingfile = optarg; break; case 'h': default: usage(); } } argc -= optind; argv += optind; /* Check if passed date has a correct format. */ if (dflag == 1) { linelength = strlen(date); if (linelength != 8) exit(EX_DATAERR); if (strspn(date, "0123456789") != 8) { fprintf(stderr, "unknown date format: %s\n", date); exit(EX_DATAERR); } } /* Save the list of passed portnames. */ if (argc != 0) { pflag = 1; while (*argv) { if ((curr = (INSTALLEDPORT *) malloc(sizeof(INSTALLEDPORT))) == NULL) (void)exit(EXIT_FAILURE); strlcpy(curr->name, *argv, strlen(*argv) + 1); curr->next = head; head = curr; (void)*argv++; } } /* * UPDATING will be parsed for all installed ports * if no portname is passed. */ if (pflag == 0) { /* Open /var/db/pkg and search for all installed ports. */ if ((dir = opendir(pkgdbpath)) != NULL) { while ((pkgdbdir = readdir(dir)) != NULL) { if (strcmp(pkgdbdir->d_name, ".") != 0 && strcmp(pkgdbdir->d_name, "..") != 0) { /* Create path to +CONTENTS file for each installed port */ n = strlcpy(tmp_file, pkgdbpath, strlen(pkgdbpath)+1); n = strlcpy(tmp_file + n, "/", sizeof(tmp_file) - n); n = strlcat(tmp_file + n, pkgdbdir->d_name, sizeof(tmp_file) - n); if (stat(tmp_file, &attribute) == -1) { fprintf(stderr, "can't open %s: %s\n", tmp_file, strerror(errno)); return EXIT_FAILURE; } if (attribute.st_mode & S_IFREG) continue; (void)strlcat(tmp_file + n, "/", sizeof(tmp_file) - n); (void)strlcat(tmp_file + n, CONTENTS_FNAME, sizeof(tmp_file) - n); /* Open +CONTENT file */ fd = fopen(tmp_file, "r"); if (fd == NULL) { fprintf(stderr, "warning: can't open %s: %s\n", tmp_file, strerror(errno)); continue; } /* * Parses +CONTENT for ORIGIN line and * put element into linked list. */ while (fgets(originline, maxcharperline, fd) != NULL) { tmpline1 = strstr(originline, origin); if (tmpline1 != NULL) { /* Tmp variable to store port name. */ char *pname; pname = strrchr(originline, (int)':'); pname++; if ((curr = (INSTALLEDPORT *) malloc(sizeof(INSTALLEDPORT))) == NULL) (void)exit(EXIT_FAILURE); if (pname[strlen(pname) - 1] == '\n') pname[strlen(pname) - 1] = '\0'; strlcpy (curr->name, pname, strlen(pname)+1); curr->next = head; head = curr; } } if (ferror(fd)) { fprintf(stderr, "error reading input\n"); exit(EX_IOERR); } (void)fclose(fd); } } closedir(dir); } } /* Fetch UPDATING file if needed and open file */ if (isURL(updatingfile)) { if ((fd = fetchGetURL(updatingfile, "")) == NULL) { fprintf(stderr, "Error: Unable to get %s: %s\n", updatingfile, fetchLastErrString); exit(EX_UNAVAILABLE); } } else { fd = fopen(updatingfile, "r"); } if (fd == NULL) { fprintf(stderr, "can't open %s: %s\n", updatingfile, strerror(errno)); exit(EX_UNAVAILABLE); } /* Parse opened UPDATING file. */ while (fgets(updatingline, maxcharperline, fd) != NULL) { /* No entry is found so far */ if (found == 0) { /* Search for AFFECTS line to parse the portname. */ tmpline1 = strstr(updatingline, affects); if (tmpline1 != NULL) { curr = head; while (curr != NULL) { tmpline2 = strstr(updatingline, curr->name); if (tmpline2 != NULL) break; curr = curr->next; } if (tmpline2 != NULL) { /* If -d is set, check if entry is newer than the date. */ if ((dflag == 1) && (strncmp(dateline, date, 8) < 0)) continue; printf("%s", dateline); printf("%s", updatingline); found = 1; } } } /* Search for the end of an entry, if not found print the line. */ else { tmpline1 = strstr(updatingline, end); if (tmpline1 == NULL) printf("%s", updatingline); else { linelength = strlen(updatingline); if (linelength == 10) found = 0; else printf("%s", updatingline); } } /* Save the actual line, it could be a date. */ dateline = strdup(updatingline); } if (ferror(fd)) { fprintf(stderr, "error reading input\n"); exit(EX_IOERR); } (void)fclose(fd); exit(EX_OK); }
/* * Try and fetch a file by URL, returning the directory name for where * it's unpacked, if successful. */ const char * fileGetURL(const char *base, const char *spec, int keep_package) { const char *rp; char *cp, *tmp; char fname[FILENAME_MAX]; char pen[FILENAME_MAX]; char pkg[FILENAME_MAX]; char buf[8192]; FILE *ftp; pid_t tpid; int pfd[2], pstat, r, w = 0; char *hint; int fd, pkgfd = 0; rp = NULL; /* Special tip that sysinstall left for us */ hint = getenv("PKG_ADD_BASE"); if (!isURL(spec)) { if (!base && !hint) return NULL; /* * We've been given an existing URL (that's known-good) and now we need * to construct a composite one out of that and the basename we were * handed as a dependency. */ if (base) { strcpy(fname, base); /* * Advance back two slashes to get to the root of the package * hierarchy */ cp = strrchr(fname, '/'); if (cp) { *cp = '\0'; /* chop name */ cp = strrchr(fname, '/'); } if (cp) { *(cp + 1) = '\0'; strcat(cp, "All/"); strcat(cp, spec); if (getenv("PACKAGESUFFIX")) strcat(cp, getenv("PACKAGESUFFIX")); else strcat(cp, ".tbz"); } else return NULL; } else { /* * Otherwise, we've been given an environment variable hinting * at the right location from sysinstall */ strcpy(fname, hint); strcat(fname, spec); if (getenv("PACKAGESUFFIX")) strcat(fname, getenv("PACKAGESUFFIX")); else strcat(fname, ".tbz"); } } else strcpy(fname, spec); if (keep_package) { tmp = getenv("PKGDIR"); strlcpy(pkg, tmp ? tmp : ".", sizeof(pkg)); tmp = basename(fname); strlcat(pkg, "/", sizeof(pkg)); strlcat(pkg, tmp, sizeof(pkg)); if ((pkgfd = open(pkg, O_WRONLY|O_CREAT|O_TRUNC, 0644)) == -1) { printf("Error: Unable to open %s\n", pkg); perror("open"); return NULL; } } fetchDebug = (Verbose > 0); if ((ftp = fetchGetURL(fname, Verbose ? "v" : NULL)) == NULL) { printf("Error: Unable to get %s: %s\n", fname, fetchLastErrString); /* If the fetch fails, yank the package. */ if (keep_package && unlink(pkg) < 0 && Verbose) { warnx("failed to remove partially fetched package: %s", pkg); } return NULL; } if (isatty(0) || Verbose) printf("Fetching %s...", fname), fflush(stdout); pen[0] = '\0'; if ((rp = make_playpen(pen, 0)) == NULL) { printf("Error: Unable to construct a new playpen for FTP!\n"); fclose(ftp); return NULL; } if (pipe(pfd) == -1) { warn("pipe()"); cleanup(0); exit(2); } if ((tpid = fork()) == -1) { warn("pipe()"); cleanup(0); exit(2); } if (!tpid) { dup2(pfd[0], 0); for (fd = getdtablesize() - 1; fd >= 3; --fd) close(fd); execl("/usr/bin/tar", "tar", Verbose ? "-xpjvf" : "-xpjf", "-", (char *)0); _exit(2); } close(pfd[0]); for (;;) { if ((r = fread(buf, 1, sizeof buf, ftp)) < 1) break; if ((w = write(pfd[1], buf, r)) != r) break; if (keep_package) { if ((w = write(pkgfd, buf, r)) != r) break; } } if (ferror(ftp)) warn("warning: error reading from server"); fclose(ftp); if (keep_package) { close(pkgfd); } close(pfd[1]); if (w == -1) warn("warning: error writing to tar"); tpid = waitpid(tpid, &pstat, 0); if (Verbose) printf("tar command returns %d status\n", WEXITSTATUS(pstat)); if (rp && (isatty(0) || Verbose)) printf(" Done.\n"); return rp; }