예제 #1
0
/*
 * 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;
}
예제 #2
0
파일: fetch.c 프로젝트: O2Graphics/pkg
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;
}
예제 #3
0
파일: fetch.c 프로젝트: Distrotech/openldap
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;
}
예제 #4
0
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;
}
예제 #5
0
파일: main.c 프로젝트: edgar-pek/PerspicuOS
/*
 * 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);
}
예제 #6
0
/*
 * 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;
}