diff options
author | jkh <jkh@FreeBSD.org> | 1995-04-26 15:08:23 +0000 |
---|---|---|
committer | jkh <jkh@FreeBSD.org> | 1995-04-26 15:08:23 +0000 |
commit | b34c5b4d3db443f8e148e5d85c898ced04119ed1 (patch) | |
tree | 8443f1b99f19a90ada9c01edc6a4ef2af7b09aa6 /usr.sbin/pkg_install/lib/file.c | |
parent | 16c38595ac3169c6cf25d7afc17b0266943c57df (diff) | |
download | FreeBSD-src-b34c5b4d3db443f8e148e5d85c898ced04119ed1.zip FreeBSD-src-b34c5b4d3db443f8e148e5d85c898ced04119ed1.tar.gz |
Add code for dealing with URLs.
Diffstat (limited to 'usr.sbin/pkg_install/lib/file.c')
-rw-r--r-- | usr.sbin/pkg_install/lib/file.c | 208 |
1 files changed, 200 insertions, 8 deletions
diff --git a/usr.sbin/pkg_install/lib/file.c b/usr.sbin/pkg_install/lib/file.c index 19470be..8c6addc 100644 --- a/usr.sbin/pkg_install/lib/file.c +++ b/usr.sbin/pkg_install/lib/file.c @@ -1,5 +1,5 @@ #ifndef lint -static const char *rcsid = "$Id: file.c,v 1.6 1994/12/06 00:51:48 jkh Exp $"; +static const char *rcsid = "$Id: file.c,v 1.7 1995/04/22 13:58:42 jkh Exp $"; #endif /* @@ -23,6 +23,8 @@ static const char *rcsid = "$Id: file.c,v 1.6 1994/12/06 00:51:48 jkh Exp $"; */ #include "lib.h" +#include <FtpLibrary.h> +#include <pwd.h> /* Quick check to see if a file exists */ Boolean @@ -81,8 +83,196 @@ isemptyfile(char *fname) return TRUE; } +/* Returns TRUE if file is a URL specification */ +Boolean +isURL(char *fname) +{ + /* + * I'm sure there are other types of URL specifications that I could + * also be looking for here, but for now I'll just be happy to get ftp + * working. + */ + while (isspace(*fname)) + ++fname; + if (!strncmp(fname, "ftp://", 6)) + return TRUE; + return FALSE; +} + +/* Returns the host part of a URL */ +char * +fileURLHost(char *fname, char *where, int max) +{ + char *ret; + + while (isspace(*fname)) + ++fname; + /* Don't ever call this on a bad URL! */ + fname += strlen("ftp://"); + /* Do we have a place to stick our work? */ + if (ret = where) { + while (*fname && *fname != '/' && max--) + *where++ = *fname++; + *where = '\0'; + return ret; + } + /* If not, they must really want us to stomp the original string */ + ret = fname; + while (*fname && *fname != '/') + ++fname; + *fname = '\0'; + return ret; +} + +/* Returns the filename part of a URL */ +char * +fileURLFilename(char *fname, char *where, int max) +{ + char *ret; + + while (isspace(*fname)) + ++fname; + /* Don't ever call this on a bad URL! */ + fname += strlen("ftp://"); + /* Do we have a place to stick our work? */ + if (ret = where) { + while (*fname && *fname != '/') + ++fname; + if (*fname == '/') { + while (*fname && max--) + *where++ = *fname++; + } + *where = '\0'; + return ret; + } + /* If not, they must really want us to stomp the original string */ + while (*fname && *fname != '/') + ++fname; + return fname; +} + +/* + * Callback functions for fileGetURL - GetIO is called on I/O requests + * and GetAbort when the transfer aborts. + */ + +/* Something they can use to keep track of the action */ +Boolean connectionAborted = FALSE; + +static int +_fileGetIO(FTP *ftp, int n, char *s ) +{ + printf("In IO: %s\n", s); + return 0; +} + +static int +_fileGetAbort(FTP *ftp, int n, char *s ) +{ + /* No access or not found, exclude network or host unreachable */ + if (abs(n) == 550 && FtpBadReply550(s)) { + connectionAborted = TRUE; + return 1; + } + return 0; +} + +#define HOSTNAME_MAX 64 + +/* + * Try and fetch a file by URL, returning the name of the local + * copy if fetched successfully. + */ +char * +fileGetURL(char *fname) +{ + static char out[FILENAME_MAX]; + char *cp; + char host[HOSTNAME_MAX], file[FILENAME_MAX], dir[FILENAME_MAX]; + char pword[HOSTNAME_MAX + 40], *uname; + struct passwd *pw; + FTP *ftp; + int i; + + if (!isURL(fname)) + return NULL; + + cp = fileURLHost(fname, host, HOSTNAME_MAX); + if (!*cp) { + whinge("URL `%s' has bad host part!", fname); + return NULL; + } + + cp = fileURLFilename(fname, file, FILENAME_MAX); + if (!*cp) { + whinge("URL `%s' has bad filename part!", fname); + return NULL; + } + + FtpSetErrorHandler(&FtpInit, _fileGetAbort); + FtpSetFlag(&FtpInit, FTP_REST); + FtpSetTimeout(&FtpInit, 60); /* XXX this may be too short */ + + /* Maybe change to ftp if this doesn't work */ + uname = "anonymous"; + + /* Make up a convincing "password" */ + pw = getpwuid(getuid()); + if (!pw) { + whinge("Can't get user name for ID %d\n.", getuid()); + strcpy(pword, "joe@"); + } + else + snprintf(pword, HOSTNAME_MAX + 40, "%s@%s", pw->pw_name, host); + if (Verbose) + printf("Trying to fetch %s from %s.\n", file, host); + + FtpLogin(&ftp, host, uname, pword, NULL); + + strcpy(dir, file); + for (i = strlen(dir); i && dir[i] != '/'; i--); + dir[i] = '\0'; + + if (dir[0]) + FtpChdir(ftp, dir); + FtpBinary(ftp); + + if ((cp = getenv("PKG_TMPDIR")) != NULL) + sprintf(out, "%s/instpkg-XXXXXX.tgz", cp); + else + strcpy(out, "/var/tmp/instpkg-XXXXXX.tgz"); + + FtpGet(ftp, basename_of(file), out); + FtpBye(ftp); + if (connectionAborted) + return NULL; + return out; +} + +char * +fileFindByPath(char *fname) +{ + static char tmp[FILENAME_MAX]; + char *cp; + + cp = getenv("PKG_PATH"); + if (!cp) + whinge("Warning: PKG_PATH environment variable not set."); + tmp[0] = '\0'; + while (cp) { + char *cp2 = strsep(&cp, ":"); + + snprintf(tmp, FILENAME_MAX, "%s/%s.tgz", cp2 ? cp2 : cp, fname); + if (fexists(tmp)) + break; + else + tmp[0] = '\0'; + } + return tmp; +} + char * -get_file_contents(char *fname) +fileGetContents(char *fname) { char *contents; struct stat sb; @@ -125,9 +315,9 @@ copy_file(char *dir, char *fname, char *to) char cmd[FILENAME_MAX]; if (fname[0] == '/') - sprintf(cmd, "cp -p -r %s %s", fname, to); + snprintf(cmd, FILENAME_MAX, "cp -p -r %s %s", fname, to); else - sprintf(cmd, "cp -p -r %s/%s %s", dir, fname, to); + snprintf(cmd, FILENAME_MAX, "cp -p -r %s/%s %s", dir, fname, to); if (vsystem(cmd)) barf("Couldn't perform '%s'", cmd); } @@ -138,9 +328,9 @@ move_file(char *dir, char *fname, char *to) char cmd[FILENAME_MAX]; if (fname[0] == '/') - sprintf(cmd, "mv %s %s", fname, to); + snprintf(cmd, FILENAME_MAX, "mv %s %s", fname, to); else - sprintf(cmd, "mv %s/%s %s", dir, fname, to); + snprintf(cmd, FILENAME_MAX, "mv %s/%s %s", dir, fname, to); if (vsystem(cmd)) barf("Couldn't perform '%s'", cmd); } @@ -162,10 +352,12 @@ copy_hierarchy(char *dir, char *fname, Boolean to) /* If absolute path, use it */ if (*fname == '/') dir = "/"; - sprintf(cmd, "tar cf - -C %s %s | tar xpf -", dir, fname); + snprintf(cmd, FILENAME_MAX * 3, "tar cf - -C %s %s | tar xpf -", + dir, fname); } else - sprintf(cmd, "tar cf - %s | tar xpf - -C %s", fname, dir); + snprintf(cmd, FILENAME_MAX * 3, "tar cf - %s | tar xpf - -C %s", + fname, dir); #ifdef DEBUG printf("Using '%s' to copy trees.\n", cmd); #endif |