int retr_file(int sock, int fd, off_t file_sz, off_t offset) { ssize_t nleft, nwritten, r; char *p; static char *buf; int ret = -1; if (buf == NULL) { /* allocate once */ if ((buf = malloc(TMPBUF_LEN)) == NULL) err(1, "retr_file: malloc"); } if (progressmeter) start_progress_meter(file_sz, &offset); while ((r = read(sock, buf, TMPBUF_LEN)) != 0) { if (r == -1) { if (errno == EINTR) goto error; err(1, "retr_file: read"); } offset += r; p = buf; nleft = r; while (nleft > 0) { nwritten = write(fd, p, nleft); switch (nwritten) { case -1: if (errno == EINTR) goto error; err(1, "retr_file: write"); /* NOT REACHED */ case 0: break; default: nleft -= nwritten; p += nwritten; } } } ret = 0; error: if (progressmeter) stop_progress_meter(); return ret; }
static void https_retr_file(const char *fn, off_t file_sz, off_t offset) { size_t wlen; ssize_t i, r; char *cp; static char *buf; int fd, flags; if (buf == NULL) { buf = malloc(TMPBUF_LEN); /* allocate once */ if (buf == NULL) err(1, "%s: malloc", __func__); } flags = O_CREAT | O_WRONLY; if (offset) flags |= O_APPEND; if (strcmp(fn, "-") == 0) fd = STDOUT_FILENO; else if ((fd = open(fn, flags, 0666)) == -1) err(1, "%s: open %s", __func__, fn); start_progress_meter(file_sz, &offset); while (1) { r = tls_read(ctx, buf, TMPBUF_LEN); if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT) continue; else if (r < 0) { errx(1, "%s: tls_read: %s", __func__, tls_error(ctx)); } if (r == 0) break; offset += r; for (cp = buf, wlen = r; wlen > 0; wlen -= i, cp += i) { if ((i = write(fd, cp, wlen)) == -1) { if (errno != EINTR) err(1, "%s: write", __func__); } else if (i == 0) break; } } if (strcmp(fn, "-") != 0) close(fd); stop_progress_meter(); }
/* * archive_read_open open callback. As we already have an open * libfetch handler all we need to do is print the download messages. */ int sum_start(struct archive *a, void *data) { Sumfile *sum = data; char *p; if (!parsable) { /* human readable output */ if ((p = strrchr(sum->url->doc, '/')) != NULL) p++; else p = (char *)sum->url->doc; /* should not happen */ printf(MSG_DOWNLOADING, p); fflush(stdout); start_progress_meter(p, sum->size, &sum->pos); } else printf(MSG_DOWNLOAD_START); return ARCHIVE_OK; }
int event_callback(void *data, struct pkg_event *ev) { struct pkg *pkg = NULL; struct pkg_dep *dep = NULL; const char *message; int *debug = data; (void)debug; switch(ev->type) { case PKG_EVENT_ERRNO: warn("%s(%s)", ev->e_errno.func, ev->e_errno.arg); break; case PKG_EVENT_ERROR: warnx("%s", ev->e_pkg_error.msg); break; case PKG_EVENT_FETCHING: if (fetched == 0) { strlcpy(url, ev->e_fetching.url, sizeof(url)); start_progress_meter(url, ev->e_fetching.total, &fetched); } fetched = ev->e_fetching.done; if (ev->e_fetching.done == ev->e_fetching.total) { stop_progress_meter(); fetched = 0; } break; case PKG_EVENT_INSTALL_BEGIN: printf("Installing %s-%s...", pkg_get(ev->e_install_begin.pkg, PKG_NAME), pkg_get(ev->e_install_begin.pkg, PKG_VERSION)); fflush(stdout); break; case PKG_EVENT_INSTALL_FINISHED: printf(" done\n"); message = pkg_get(ev->e_install_finished.pkg, PKG_MESSAGE); if (message != NULL && message[0] != '\0') printf("%s\n", message); break; case PKG_EVENT_DEINSTALL_BEGIN: printf("Deinstalling %s-%s...", pkg_get(ev->e_deinstall_begin.pkg, PKG_NAME), pkg_get(ev->e_deinstall_begin.pkg, PKG_VERSION)); fflush(stdout); break; case PKG_EVENT_DEINSTALL_FINISHED: printf(" done\n"); break; case PKG_EVENT_UPGRADE_BEGIN: printf("Upgrading %s from %s to %s...", pkg_get(ev->e_upgrade_finished.pkg, PKG_NAME), pkg_get(ev->e_upgrade_finished.pkg, PKG_VERSION), pkg_get(ev->e_upgrade_finished.pkg, PKG_NEWVERSION)); fflush(stdout); break; case PKG_EVENT_UPGRADE_FINISHED: printf("done\n"); break; case PKG_EVENT_REQUIRED: pkg = ev->e_required.pkg; fprintf(stderr, "%s-%s is required by:", pkg_get(pkg, PKG_NAME), pkg_get(pkg, PKG_VERSION)); while (pkg_rdeps(pkg, &dep) == EPKG_OK) { fprintf(stderr, " %s-%s", pkg_dep_name(dep), pkg_dep_version(dep)); } if (ev->e_required.force == 1) fprintf(stderr, ", deleting anyway\n"); else fprintf(stderr, "\n"); break; case PKG_EVENT_ALREADY_INSTALLED: printf("%s-%s already installed\n", pkg_get(ev->e_already_installed.pkg, PKG_NAME), pkg_get(ev->e_already_installed.pkg, PKG_VERSION)); break; default: break; } return 0; }
void DownloadFileWithCompression(struct ORACLEALLINONE *oraAllInOne, char* pDirectory, int compressionLevel, char* pRemoteFile, char* pLocalFile, int isKeepPartial, int isResume) { FILE *fp; sword ociResult; ub4 vCompressionLevel; ub8 vSkipBytes; char blobBuffer[ORA_BLOB_BUFFER_SIZE]; oraub8 vSize; int zRet; z_stream zStrm; unsigned char zOut[ORA_BLOB_BUFFER_SIZE]; #ifndef _WIN32 int showProgress; char progressLine[MAX_FMT_SIZE]; #endif int isStdUsed; off_t cnt; off_t sourceSize; struct stat fileStat; struct BINDVARIABLE oraBindsDownload[] = { { 0, SQLT_STR, ":directory", pDirectory, ORA_IDENTIFIER_SIZE + 1 }, { 0, SQLT_INT, ":compression_level", &vCompressionLevel, sizeof(vCompressionLevel) }, { 0, SQLT_STR, ":filename", pRemoteFile, MAX_FMT_SIZE }, { 0, SQLT_BLOB, ":blob", &oraAllInOne->blob, sizeof(oraAllInOne->blob) }, { 0, SQLT_INT, ":skipbytes", &vSkipBytes, sizeof(vSkipBytes) }, { 0 } }; struct ORACLESTATEMENT oraStmtDownload = { #include "downloadcompr.text" , 0, oraBindsDownload, NO_ORACLE_DEFINES }; vCompressionLevel = compressionLevel; isStdUsed = !strcmp(pLocalFile, "-"); if (isStdUsed) { isResume = 0; isKeepPartial = 1; } SetSessionAction(oraAllInOne, "GZIP_AND_DOWNLOAD: GZIP"); if (OCIDescriptorAlloc(oraAllInOne->envhp, (void**)&oraAllInOne->blob, OCI_DTYPE_LOB, 0, 0)) { ExitWithError(oraAllInOne, RET_OCIINIT, ERROR_NONE, "Failed to allocate BLOB\n"); } cnt = 0; vSkipBytes = 0; if (isResume) { if (!stat(pLocalFile, &fileStat)) vSkipBytes = cnt = fileStat.st_size; if (!cnt) isResume = 0; } #ifndef _WIN32 showProgress = 1; if (!isatty(STDOUT_FILENO) || isStdUsed) showProgress = 0; if (showProgress) start_longops_meter(oraAllInOne, 0, 1); #endif PrepareStmtAndBind(oraAllInOne, &oraStmtDownload); ociResult = ExecuteStmt(oraAllInOne); #ifndef _WIN32 if (showProgress) stop_longops_meter(); #endif if (ociResult) ExitWithError(oraAllInOne, RET_ORA, ERROR_OCI, "Failed to compress file in oracle directory\n"); #ifndef _WIN32 if (showProgress) { if (OCILobGetLength2(oraAllInOne->svchp[0], oraAllInOne->errhp, oraAllInOne->blob, (oraub8*)&sourceSize)) ExitWithError(oraAllInOne, RET_ORA, ERROR_OCI, "Error getting BLOB length\n"); strcpy(progressLine, "TRANSFER & GUNZIP: "); strncat(progressLine, basename(pLocalFile), MAX_FMT_SIZE - 1 - strlen(progressLine)); start_progress_meter(progressLine, sourceSize, &cnt); } #endif SetSessionAction(oraAllInOne, "GZIP_AND_DOWNLOAD: DOWNLOAD"); if (!isStdUsed && (fp = fopen(pLocalFile, isResume ? "ab" : "wb")) == NULL) { ExitWithError(oraAllInOne, RET_FS, ERROR_OS, "Error opening a local file for writing\n"); } if (isStdUsed) fp = stdout; zStrm.zalloc = Z_NULL; zStrm.zfree = Z_NULL; zStrm.opaque = Z_NULL; zStrm.avail_in = 0; zStrm.next_in = Z_NULL; zRet = inflateInit2(&zStrm, 16+MAX_WBITS); if (zRet != Z_OK) { if (!isStdUsed) fclose(fp); ExitWithError(oraAllInOne, RET_ZLIB, ERROR_NONE, "ZLIB initialization failed\n"); } vSize = 0; ociResult = OCILobRead2(oraAllInOne->svchp[0], oraAllInOne->errhp, oraAllInOne->blob, &vSize, 0, 1, blobBuffer, ORA_BLOB_BUFFER_SIZE, OCI_FIRST_PIECE, 0, 0, 0, 0); while (ociResult == OCI_NEED_DATA || ociResult == OCI_SUCCESS) { cnt += vSize; zStrm.avail_in = vSize; zStrm.next_in = blobBuffer; do { zStrm.avail_out = ORA_BLOB_BUFFER_SIZE; zStrm.next_out = zOut; zRet = inflate(&zStrm, Z_NO_FLUSH); switch (zRet) { case Z_STREAM_ERROR: case Z_NEED_DICT: case Z_DATA_ERROR: case Z_MEM_ERROR: (void)inflateEnd(&zStrm); if (!isStdUsed) fclose(fp); ExitWithError(oraAllInOne, RET_ZLIB, ERROR_NONE, "ZLIB inflate failed: %d, size %d\n", zRet, vSize); } fwrite(zOut, sizeof(unsigned char), ORA_BLOB_BUFFER_SIZE - zStrm.avail_out, fp); if (ferror(fp)) { (void)inflateEnd(&zStrm); if (!isStdUsed) fclose(fp); ExitWithError(oraAllInOne, RET_DONOTEXIT, ERROR_OS, "Error writing to a local file\n"); if (!isKeepPartial) { if (unlink(pLocalFile)) ExitWithError(oraAllInOne, RET_FS, ERROR_OS, "Could not remove partial file %s\n", pLocalFile); } ExitWithError(oraAllInOne, RET_FS, ERROR_NONE, 0); } } while (zStrm.avail_out == 0); if (ociResult == OCI_SUCCESS) break; ociResult = OCILobRead2(oraAllInOne->svchp[0], oraAllInOne->errhp, oraAllInOne->blob, &vSize, 0, 1, blobBuffer, ORA_BLOB_BUFFER_SIZE, OCI_NEXT_PIECE, 0, 0, 0, 0); } #ifndef _WIN32 if (showProgress) stop_progress_meter(); #endif inflateEnd(&zStrm); if (!isStdUsed) fclose(fp); if (ociResult != OCI_SUCCESS) { ExitWithError(oraAllInOne, RET_ORA, ERROR_OCI, "Error reading BLOB\n"); } ReleaseStmt(oraAllInOne); SetSessionAction(oraAllInOne, 0); OCILobFreeTemporary(oraAllInOne->svchp[0], oraAllInOne->errhp, oraAllInOne->blob); if (OCIDescriptorFree(oraAllInOne->blob, OCI_DTYPE_LOB)) { ExitWithError(oraAllInOne, RET_OCIINIT, ERROR_NONE, "Failed to free BLOB\n"); } oraAllInOne->blob = 0; } void UploadFileWithCompression(struct ORACLEALLINONE *oraAllInOne, char* pDirectory, int compressionLevel, char* pRemoteFile, char* pLocalFile, int isKeepPartial, int isResume) { FILE *fp; sword ociResult; char blobBuffer[ORA_BLOB_BUFFER_SIZE]; oraub8 vSize; ub8 vSkippedBytes; char vOpenMode[3]; ub1 piece; int zRet, zFlush; z_stream zStrm; unsigned char zIn[ORA_BLOB_BUFFER_SIZE]; #ifndef _WIN32 int showProgress; char progressLine[MAX_FMT_SIZE]; #endif int isStdUsed; off_t cnt; off_t sourceSize; struct stat fileStat; int isError; struct ORACLEFILEATTR oracleFileAttr; struct BINDVARIABLE oraBindsUpload[] = { { 0, SQLT_STR, ":directory", pDirectory, ORA_IDENTIFIER_SIZE + 1 }, { 0, SQLT_STR, ":filename", pRemoteFile, MAX_FMT_SIZE }, { 0, SQLT_STR, ":openmode", vOpenMode, sizeof(vOpenMode) }, { 0, SQLT_INT, ":file_size", &sourceSize, sizeof(sourceSize) }, { 0, SQLT_INT, ":skipped", &vSkippedBytes, sizeof(vSkippedBytes) }, { 0, SQLT_BLOB, ":blob", &oraAllInOne->blob, sizeof(oraAllInOne->blob) }, { 0 } }; struct ORACLESTATEMENT oraStmtUpload = { #include "uploadcompr.text" , 0, oraBindsUpload, NO_ORACLE_DEFINES }; isStdUsed = !strcmp(pLocalFile, "-"); if (isStdUsed) isResume = 0; SetSessionAction(oraAllInOne, "UPLOAD_AND_GUNZIP: UPLOAD"); if (OCIDescriptorAlloc(oraAllInOne->envhp, (void**)&oraAllInOne->blob, OCI_DTYPE_LOB, 0, 0)) { ExitWithError(oraAllInOne, RET_OCIINIT, ERROR_NONE, "Failed to allocate BLOB\n"); } if (OCILobCreateTemporary(oraAllInOne->svchp[0], oraAllInOne->errhp, oraAllInOne->blob, OCI_DEFAULT, 0, OCI_TEMP_BLOB, TRUE/*cache*/, OCI_DURATION_SESSION)) { ExitWithError(oraAllInOne, RET_ORA, ERROR_OCI, "Failed to create temporary BLOB\n"); } piece = OCI_FIRST_PIECE; #ifndef _WIN32 showProgress = 1; if (!isatty(STDOUT_FILENO) || isStdUsed) showProgress = 0; #endif cnt = vSkippedBytes = 0; if (isResume) { GetOracleFileAttr(oraAllInOne, pDirectory, pRemoteFile, &oracleFileAttr); if (oracleFileAttr.bExists) cnt = vSkippedBytes = oracleFileAttr.length; if (!cnt) isResume = 0; } #ifndef _WIN32 if (showProgress) { stat(pLocalFile, &fileStat); sourceSize = fileStat.st_size; strcpy(progressLine, "GZIP & TRANSFER: "); strncat(progressLine, basename(pLocalFile), MAX_FMT_SIZE - 1 - strlen(progressLine)); start_progress_meter(progressLine, sourceSize, &cnt); } #endif if (!isStdUsed && (fp = fopen(pLocalFile, "rb")) == NULL) { ExitWithError(oraAllInOne, RET_FS, ERROR_OS, "Error opening a local file for reading\n"); } if (isStdUsed) fp = stdin; if (cnt > 0) { if (fseek(fp, cnt, SEEK_SET)) { fclose(fp); ExitWithError(oraAllInOne, RET_FS, ERROR_OS, "Error setting reading position in a local file\n"); } } zStrm.zalloc = Z_NULL; zStrm.zfree = Z_NULL; zStrm.opaque = Z_NULL; zRet = deflateInit2(&zStrm, compressionLevel ? compressionLevel : Z_DEFAULT_COMPRESSION, Z_DEFLATED, 16+MAX_WBITS, 8, Z_DEFAULT_STRATEGY); if (zRet != Z_OK) { if (!isStdUsed) fclose(fp); ExitWithError(oraAllInOne, RET_ZLIB, ERROR_NONE, "ZLIB initialization failed\n"); } while (!feof(fp)) { zStrm.avail_in = fread(zIn, sizeof(unsigned char), sizeof(zIn), fp); cnt += zStrm.avail_in; if (ferror(fp)) { (void)deflateEnd(&zStrm); if (!isStdUsed) fclose(fp); ExitWithError(oraAllInOne, RET_FS, ERROR_OS, "Error reading from a local file\n"); } zFlush = feof(fp) ? Z_FINISH : Z_NO_FLUSH; zStrm.next_in = zIn; do { zStrm.avail_out = ORA_BLOB_BUFFER_SIZE; zStrm.next_out = blobBuffer; zRet = deflate(&zStrm, zFlush); if (zRet != Z_OK && zRet != Z_STREAM_END && zRet != Z_BUF_ERROR) { (void)deflateEnd(&zStrm); if (!isStdUsed) fclose(fp); ExitWithError(oraAllInOne, RET_ZLIB, ERROR_NONE, "ZLIB deflate failed: %d, size %d\n", zRet, zStrm.avail_in); } if (zRet == Z_STREAM_END) piece = (piece == OCI_FIRST_PIECE) ? OCI_ONE_PIECE : OCI_LAST_PIECE; vSize = (piece == OCI_ONE_PIECE) ? ORA_BLOB_BUFFER_SIZE - zStrm.avail_out : 0; if (zStrm.avail_out == ORA_BLOB_BUFFER_SIZE) continue; ociResult = OCILobWrite2(oraAllInOne->svchp[0], oraAllInOne->errhp, oraAllInOne->blob, &vSize, 0, 1, blobBuffer, ORA_BLOB_BUFFER_SIZE - zStrm.avail_out, piece, 0, 0, 0, 0); if (ociResult != OCI_NEED_DATA && ociResult) { (void)deflateEnd(&zStrm); if (!isStdUsed) fclose(fp); ExitWithError(oraAllInOne, RET_ORA, ERROR_OCI, "Error writing to BLOB\n"); } if (piece == OCI_FIRST_PIECE) piece = OCI_NEXT_PIECE; } while (zStrm.avail_out == 0); } #ifndef _WIN32 if (showProgress) stop_progress_meter(); #endif deflateEnd(&zStrm); if (!isStdUsed) fclose(fp); isError = 0; strcpy(vOpenMode, isResume ? "ab" : "wb"); SetSessionAction(oraAllInOne, "UPLOAD_AND_GUNZIP: GUNZIP"); #ifndef _WIN32 if (showProgress) start_longops_meter(oraAllInOne, 0, 1); #endif PrepareStmtAndBind(oraAllInOne, &oraStmtUpload); ociResult = ExecuteStmt(oraAllInOne); #ifndef _WIN32 if (showProgress) stop_longops_meter(); #endif if (ociResult) { ExitWithError(oraAllInOne, RET_DONOTEXIT, ERROR_OCI, "Failed to decompress file in oracle directory\n"); isError = 1; } else ReleaseStmt(oraAllInOne); SetSessionAction(oraAllInOne, 0); OCILobFreeTemporary(oraAllInOne->svchp[0], oraAllInOne->errhp, oraAllInOne->blob); if (OCIDescriptorFree(oraAllInOne->blob, OCI_DTYPE_LOB)) { if (!isError) ExitWithError(oraAllInOne, RET_DONOTEXIT, ERROR_NONE, "Failed to free BLOB\n"); isError = 1; } oraAllInOne->blob = 0; if (isError) { if (!isKeepPartial) Rm(oraAllInOne, pDirectory, pRemoteFile); ExitWithError(oraAllInOne, RET_ORA, ERROR_NONE, 0); } }
void sink(int argc, char **argv) { static BUF buffer; struct stat stb; enum { YES, NO, DISPLAYED } wrerr; BUF *bp; off_t i; size_t j, count; int amt, exists, first, ofd; mode_t mode, omode, mask; off_t size, statbytes; unsigned long long ull; int setimes, targisdir, wrerrno = 0; char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; struct timeval tv[2]; #define atime tv[0] #define mtime tv[1] #define SCREWUP(str) { why = str; goto screwup; } setimes = targisdir = 0; mask = umask(0); if (!pflag) (void) umask(mask); if (argc != 1) { run_err("ambiguous target"); exit(1); } targ = *argv; if (targetshouldbedirectory) verifydir(targ); (void) atomicio(vwrite, remout, "", 1); if (stat(targ, &stb) == 0 && S_ISDIR(stb.st_mode)) targisdir = 1; for (first = 1;; first = 0) { cp = buf; if (atomicio(read, remin, cp, 1) != 1) return; if (*cp++ == '\n') SCREWUP("unexpected <newline>"); do { if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch)) SCREWUP("lost connection"); *cp++ = ch; } while (cp < &buf[sizeof(buf) - 1] && ch != '\n'); *cp = 0; if (verbose_mode) fprintf(stderr, "Sink: %s", buf); if (buf[0] == '\01' || buf[0] == '\02') { if (iamremote == 0) (void) atomicio(vwrite, STDERR_FILENO, buf + 1, strlen(buf + 1)); if (buf[0] == '\02') exit(1); ++errs; continue; } if (buf[0] == 'E') { (void) atomicio(vwrite, remout, "", 1); return; } if (ch == '\n') *--cp = 0; cp = buf; if (*cp == 'T') { setimes++; cp++; if (!isdigit((unsigned char)*cp)) SCREWUP("mtime.sec not present"); ull = strtoull(cp, &cp, 10); if (!cp || *cp++ != ' ') SCREWUP("mtime.sec not delimited"); if ((time_t)ull < 0 || (unsigned long long)(time_t)ull != ull) setimes = 0; /* out of range */ mtime.tv_sec = ull; mtime.tv_usec = strtol(cp, &cp, 10); if (!cp || *cp++ != ' ' || mtime.tv_usec < 0 || mtime.tv_usec > 999999) SCREWUP("mtime.usec not delimited"); if (!isdigit((unsigned char)*cp)) SCREWUP("atime.sec not present"); ull = strtoull(cp, &cp, 10); if (!cp || *cp++ != ' ') SCREWUP("atime.sec not delimited"); if ((time_t)ull < 0 || (unsigned long long)(time_t)ull != ull) setimes = 0; /* out of range */ atime.tv_sec = ull; atime.tv_usec = strtol(cp, &cp, 10); if (!cp || *cp++ != '\0' || atime.tv_usec < 0 || atime.tv_usec > 999999) SCREWUP("atime.usec not delimited"); (void) atomicio(vwrite, remout, "", 1); continue; } if (*cp != 'C' && *cp != 'D') { /* * Check for the case "rcp remote:foo\* local:bar". * In this case, the line "No match." can be returned * by the shell before the rcp command on the remote is * executed so the ^Aerror_message convention isn't * followed. */ if (first) { run_err("%s", cp); exit(1); } SCREWUP("expected control record"); } mode = 0; for (++cp; cp < buf + 5; cp++) { if (*cp < '0' || *cp > '7') SCREWUP("bad mode"); mode = (mode << 3) | (*cp - '0'); } if (*cp++ != ' ') SCREWUP("mode not delimited"); for (size = 0; isdigit((unsigned char)*cp);) size = size * 10 + (*cp++ - '0'); if (*cp++ != ' ') SCREWUP("size not delimited"); if ((strchr(cp, '/') != NULL) || (strcmp(cp, "..") == 0)) { run_err("error: unexpected filename: %s", cp); exit(1); } if (targisdir) { static char *namebuf; static size_t cursize; size_t need; need = strlen(targ) + strlen(cp) + 250; if (need > cursize) { free(namebuf); namebuf = xmalloc(need); cursize = need; } (void) snprintf(namebuf, need, "%s%s%s", targ, strcmp(targ, "/") ? "/" : "", cp); np = namebuf; } else np = targ; curfile = cp; exists = stat(np, &stb) == 0; if (buf[0] == 'D') { int mod_flag = pflag; if (!iamrecursive) SCREWUP("received directory without -r"); if (exists) { if (!S_ISDIR(stb.st_mode)) { errno = ENOTDIR; goto bad; } if (pflag) (void) chmod(np, mode); } else { /* Handle copying from a read-only directory */ mod_flag = 1; if (mkdir(np, mode | S_IRWXU) < 0) goto bad; } vect[0] = xstrdup(np); sink(1, vect); if (setimes) { setimes = 0; if (utimes(vect[0], tv) < 0) run_err("%s: set times: %s", vect[0], strerror(errno)); } if (mod_flag) (void) chmod(vect[0], mode); free(vect[0]); continue; } omode = mode; mode |= S_IWUSR; if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { bad: run_err("%s: %s", np, strerror(errno)); continue; } (void) atomicio(vwrite, remout, "", 1); if ((bp = allocbuf(&buffer, ofd, COPY_BUFLEN)) == NULL) { (void) close(ofd); continue; } cp = bp->buf; wrerr = NO; statbytes = 0; if (showprogress) start_progress_meter(curfile, size, &statbytes); set_nonblock(remin); for (count = i = 0; i < size; i += bp->cnt) { amt = bp->cnt; if (i + amt > size) amt = size - i; count += amt; do { j = atomicio6(read, remin, cp, amt, scpio, &statbytes); if (j == 0) { run_err("%s", j != EPIPE ? strerror(errno) : "dropped connection"); exit(1); } amt -= j; cp += j; } while (amt > 0); if (count == bp->cnt) { /* Keep reading so we stay sync'd up. */ if (wrerr == NO) { if (atomicio(vwrite, ofd, bp->buf, count) != count) { wrerr = YES; wrerrno = errno; } } count = 0; cp = bp->buf; } } unset_nonblock(remin); if (showprogress) stop_progress_meter(); if (count != 0 && wrerr == NO && atomicio(vwrite, ofd, bp->buf, count) != count) { wrerr = YES; wrerrno = errno; } if (wrerr == NO && (!exists || S_ISREG(stb.st_mode)) && ftruncate(ofd, size) != 0) { run_err("%s: truncate: %s", np, strerror(errno)); wrerr = DISPLAYED; } if (pflag) { if (exists || omode != mode) #ifdef HAVE_FCHMOD if (fchmod(ofd, omode)) { #else /* HAVE_FCHMOD */ if (chmod(np, omode)) { #endif /* HAVE_FCHMOD */ run_err("%s: set mode: %s", np, strerror(errno)); wrerr = DISPLAYED; } } else { if (!exists && omode != mode) #ifdef HAVE_FCHMOD if (fchmod(ofd, omode & ~mask)) { #else /* HAVE_FCHMOD */ if (chmod(np, omode & ~mask)) { #endif /* HAVE_FCHMOD */ run_err("%s: set mode: %s", np, strerror(errno)); wrerr = DISPLAYED; } } if (close(ofd) == -1) { wrerr = YES; wrerrno = errno; } (void) response(); if (setimes && wrerr == NO) { setimes = 0; if (utimes(np, tv) < 0) { run_err("%s: set times: %s", np, strerror(errno)); wrerr = DISPLAYED; } } switch (wrerr) { case YES: run_err("%s: %s", np, strerror(wrerrno)); break; case NO: (void) atomicio(vwrite, remout, "", 1); break; case DISPLAYED: break; } } screwup: run_err("protocol error: %s", why); exit(1); } int response(void) { char ch, *cp, resp, rbuf[2048]; if (atomicio(read, remin, &resp, sizeof(resp)) != sizeof(resp)) lostconn(0); cp = rbuf; switch (resp) { case 0: /* ok */ return (0); default: *cp++ = resp; /* FALLTHROUGH */ case 1: /* error, followed by error msg */ case 2: /* fatal error, "" */ do { if (atomicio(read, remin, &ch, sizeof(ch)) != sizeof(ch)) lostconn(0); *cp++ = ch; } while (cp < &rbuf[sizeof(rbuf) - 1] && ch != '\n'); if (!iamremote) (void) atomicio(vwrite, STDERR_FILENO, rbuf, cp - rbuf); ++errs; if (resp == 1) return (-1); exit(1); } /* NOTREACHED */ } void usage(void) { (void) fprintf(stderr, "usage: scp [-12346BCpqrv] [-c cipher] [-F ssh_config] [-i identity_file]\n" " [-l limit] [-o ssh_option] [-P port] [-S program]\n" " [[user@]host1:]file1 ... [[user@]host2:]file2\n"); exit(1); }
void source(int argc, char **argv) { struct stat stb; static BUF buffer; BUF *bp; off_t i, statbytes; size_t amt, nr; int fd = -1, haderr, indx; char *last, *name, buf[2048], encname[MAXPATHLEN]; int len; for (indx = 0; indx < argc; ++indx) { name = argv[indx]; statbytes = 0; len = strlen(name); while (len > 1 && name[len-1] == '/') name[--len] = '\0'; if ((fd = open(name, O_RDONLY|O_NONBLOCK, 0)) < 0) goto syserr; if (strchr(name, '\n') != NULL) { strnvis(encname, name, sizeof(encname), VIS_NL); name = encname; } if (fstat(fd, &stb) < 0) { syserr: run_err("%s: %s", name, strerror(errno)); goto next; } if (stb.st_size < 0) { run_err("%s: %s", name, "Negative file size"); goto next; } unset_nonblock(fd); switch (stb.st_mode & S_IFMT) { case S_IFREG: break; case S_IFDIR: if (iamrecursive) { rsource(name, &stb); goto next; } /* FALLTHROUGH */ default: run_err("%s: not a regular file", name); goto next; } if ((last = strrchr(name, '/')) == NULL) last = name; else ++last; curfile = last; if (pflag) { if (do_times(remout, verbose_mode, &stb) < 0) goto next; } #define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) snprintf(buf, sizeof buf, "C%04o %lld %s\n", (u_int) (stb.st_mode & FILEMODEMASK), (long long)stb.st_size, last); if (verbose_mode) { fprintf(stderr, "Sending file modes: %s", buf); } (void) atomicio(vwrite, remout, buf, strlen(buf)); if (response() < 0) goto next; if ((bp = allocbuf(&buffer, fd, COPY_BUFLEN)) == NULL) { next: if (fd != -1) { (void) close(fd); fd = -1; } continue; } if (showprogress) start_progress_meter(curfile, stb.st_size, &statbytes); set_nonblock(remout); for (haderr = i = 0; i < stb.st_size; i += bp->cnt) { amt = bp->cnt; if (i + (off_t)amt > stb.st_size) amt = stb.st_size - i; if (!haderr) { if ((nr = atomicio(read, fd, bp->buf, amt)) != amt) { haderr = errno; memset(bp->buf + nr, 0, amt - nr); } } /* Keep writing after error to retain sync */ if (haderr) { (void)atomicio(vwrite, remout, bp->buf, amt); memset(bp->buf, 0, amt); continue; } if (atomicio6(vwrite, remout, bp->buf, amt, scpio, &statbytes) != amt) haderr = errno; } unset_nonblock(remout); if (showprogress) stop_progress_meter(); if (fd != -1) { if (close(fd) < 0 && !haderr) haderr = errno; fd = -1; } if (!haderr) (void) atomicio(vwrite, remout, "", 1); else run_err("%s: %s", name, strerror(haderr)); (void) response(); } }
/* if db_mtime == NULL, we're downloading a package, pkg_summary otherwise */ Dlfile * download_file(char *str_url, time_t *db_mtime) { /* from pkg_install/files/admin/audit.c */ Dlfile *file; char *p; size_t buf_len, buf_fetched; ssize_t cur_fetched; off_t statsize; time_t begin_dl, now; struct url_stat st; struct url *url; fetchIO *f = NULL; url = fetchParseURL(str_url); if (url == NULL || (f = fetchXGet(url, &st, "")) == NULL) return NULL; if (st.size == -1) { /* could not obtain file size */ if (db_mtime != NULL) /* we're downloading pkg_summary */ *db_mtime = 0; /* not -1, don't force update */ return NULL; } if (db_mtime != NULL) { if (st.mtime <= *db_mtime) { /* -1 used to identify return type, local summary up-to-date */ *db_mtime = -1; fetchIO_close(f); return NULL; } *db_mtime = st.mtime; } if ((p = strrchr(str_url, '/')) != NULL) p++; else p = (char *)str_url; /* should not happen */ #ifndef _MINIX /* XXX: SSIZE_MAX fails under MINIX */ /* st.size is an off_t, it will be > SSIZE_MAX on 32 bits systems */ if (sizeof(st.size) == sizeof(SSIZE_MAX) && st.size > SSIZE_MAX - 1) err(EXIT_FAILURE, "file is too large"); #endif buf_len = st.size; XMALLOC(file, sizeof(Dlfile)); XMALLOC(file->buf, buf_len + 1); printf(MSG_DOWNLOADING, p); fflush(stdout); buf_fetched = 0; begin_dl = time(NULL); statsize = 0; start_progress_meter(p, buf_len, &statsize); while (buf_fetched < buf_len) { cur_fetched = fetchIO_read(f, file->buf + buf_fetched, fetch_buffer); if (cur_fetched == 0) errx(EXIT_FAILURE, "truncated file"); else if (cur_fetched == -1) errx(EXIT_FAILURE, "failure during fetch of file: %s", fetchLastErrString); buf_fetched += cur_fetched; statsize += cur_fetched; now = time(NULL); } stop_progress_meter(); file->buf[buf_len] = '\0'; file->size = buf_len; if (file->buf[0] == '\0') errx(EXIT_FAILURE, "empty download, exiting.\n"); fetchIO_close(f); return file; }
int event_callback(void *data, struct pkg_event *ev) { struct pkg *pkg = NULL; int *debug = data; (void) debug; const char *filename; struct pkg_event_conflict *cur_conflict; switch(ev->type) { case PKG_EVENT_ERRNO: warnx("%s(%s): %s", ev->e_errno.func, ev->e_errno.arg, strerror(ev->e_errno.no)); break; case PKG_EVENT_ERROR: warnx("%s", ev->e_pkg_error.msg); break; case PKG_EVENT_NOTICE: if (!quiet) warnx("%s", ev->e_pkg_notice.msg); break; case PKG_EVENT_DEVELOPER_MODE: warnx("DEVELOPER_MODE: %s", ev->e_pkg_error.msg); break; case PKG_EVENT_FETCHING: if (quiet || !isatty(fileno(stdin))) break; if (fetched == 0) { filename = strrchr(ev->e_fetching.url, '/'); if (filename != NULL) { filename++; } else { /* * We failed at being smart, so display * the entire url. */ filename = ev->e_fetching.url; } strlcpy(url, filename, sizeof(url)); start_progress_meter(url, ev->e_fetching.total, &fetched); } fetched = ev->e_fetching.done; if (ev->e_fetching.done == ev->e_fetching.total) { stop_progress_meter(); fetched = 0; } break; case PKG_EVENT_INSTALL_BEGIN: if (quiet) break; else { struct sbuf *msg; nbdone++; msg = sbuf_new_auto(); if (msg == NULL) { warn("sbuf_new_auto() failed"); break; } print_status_begin(msg); pkg = ev->e_install_begin.pkg; pkg_sbuf_printf(msg, "Installing %n-%v...", pkg, pkg); print_status_end(msg); } break; case PKG_EVENT_INSTALL_FINISHED: if (quiet) break; printf(" done\n"); if (pkg_has_message(ev->e_install_finished.pkg)) { if (messages == NULL) messages = sbuf_new_auto(); pkg_sbuf_printf(messages, "%M\n", ev->e_install_finished.pkg); } break; case PKG_EVENT_INTEGRITYCHECK_BEGIN: if (quiet) break; printf("Checking integrity..."); break; case PKG_EVENT_INTEGRITYCHECK_FINISHED: if (quiet) break; printf(" done\n"); break; case PKG_EVENT_INTEGRITYCHECK_CONFLICT: printf("\nConflict found on path %s between %s-%s(%s) and ", ev->e_integrity_conflict.pkg_path, ev->e_integrity_conflict.pkg_name, ev->e_integrity_conflict.pkg_version, ev->e_integrity_conflict.pkg_origin); cur_conflict = ev->e_integrity_conflict.conflicts; while (cur_conflict) { if (cur_conflict->next) printf("%s-%s(%s), ", cur_conflict->name, cur_conflict->version, cur_conflict->origin); else printf("%s-%s(%s)", cur_conflict->name, cur_conflict->version, cur_conflict->origin); cur_conflict = cur_conflict->next; } printf("\n"); break; case PKG_EVENT_DEINSTALL_BEGIN: if (quiet) break; else { struct sbuf *msg; nbdone++; msg = sbuf_new_auto(); if (msg == NULL) { warn("sbuf_new_auto() failed"); break; } print_status_begin(msg); pkg = ev->e_install_begin.pkg; pkg_sbuf_printf(msg, "Deleting %n-%v...", pkg, pkg); print_status_end(msg); } break; case PKG_EVENT_DEINSTALL_FINISHED: if (quiet) break; printf(" done\n"); break; case PKG_EVENT_UPGRADE_BEGIN: if (quiet) break; else { struct sbuf *msg; pkg = ev->e_upgrade_begin.pkg; nbdone++; msg = sbuf_new_auto(); if (msg == NULL) { warn("sbuf_new_auto() failed"); break; } print_status_begin(msg); switch (pkg_version_change(pkg)) { case PKG_DOWNGRADE: pkg_sbuf_printf(msg, "Downgrading %n from %V to %v...", pkg, pkg, pkg); break; case PKG_REINSTALL: pkg_sbuf_printf(msg, "Reinstalling %n-%V...", pkg, pkg); break; case PKG_UPGRADE: pkg_sbuf_printf(msg, "Upgrading %n from %V to %v...", pkg, pkg, pkg); break; } print_status_end(msg); } break; case PKG_EVENT_UPGRADE_FINISHED: if (quiet) break; printf(" done\n"); if (pkg_has_message(ev->e_upgrade_finished.pkg)) { if (messages == NULL) messages = sbuf_new_auto(); pkg_sbuf_printf(messages, "%M\n", ev->e_upgrade_finished.pkg); } break; case PKG_EVENT_LOCKED: pkg = ev->e_locked.pkg; pkg_fprintf(stderr, "\n%n-%v is locked and may not be modified\n", pkg, pkg); break; case PKG_EVENT_REQUIRED: pkg = ev->e_required.pkg; pkg_fprintf(stderr, "\n%n-%v is required by: %r%{%rn-%rv%| %}", pkg, pkg, pkg); if (ev->e_required.force == 1) fprintf(stderr, ", deleting anyway\n"); else fprintf(stderr, "\n"); break; case PKG_EVENT_ALREADY_INSTALLED: if (quiet) break; pkg = ev->e_already_installed.pkg; pkg_printf("%n-%v already installed\n", pkg, pkg); break; case PKG_EVENT_NOT_FOUND: printf("Package '%s' was not found in " "the repositories\n", ev->e_not_found.pkg_name); break; case PKG_EVENT_MISSING_DEP: fprintf(stderr, "missing dependency %s-%s\n", pkg_dep_name(ev->e_missing_dep.dep), pkg_dep_version(ev->e_missing_dep.dep)); break; case PKG_EVENT_NOREMOTEDB: fprintf(stderr, "Unable to open remote database \"%s\". " "Try running '%s update' first.\n", ev->e_remotedb.repo, getprogname()); break; case PKG_EVENT_NOLOCALDB: fprintf(stderr, "Local package database nonexistent!\n"); break; case PKG_EVENT_NEWPKGVERSION: newpkgversion = true; printf("New version of pkg detected; it needs to be " "installed first.\n"); break; case PKG_EVENT_FILE_MISMATCH: pkg = ev->e_file_mismatch.pkg; pkg_fprintf(stderr, "%n-%v: checksum mismatch for %S\n", pkg, pkg, pkg_file_path(ev->e_file_mismatch.file)); break; case PKG_EVENT_PLUGIN_ERRNO: warnx("%s: %s(%s): %s", pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME), ev->e_plugin_errno.func, ev->e_plugin_errno.arg, strerror(ev->e_plugin_errno.no)); break; case PKG_EVENT_PLUGIN_ERROR: warnx("%s: %s", pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME), ev->e_plugin_error.msg); break; case PKG_EVENT_PLUGIN_INFO: if (quiet) break; printf("%s: %s\n", pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME), ev->e_plugin_info.msg); break; case PKG_EVENT_INCREMENTAL_UPDATE: if (!quiet) printf("Incremental update completed, %d packages " "processed:\n" "%d packages updated, %d removed and %d added.\n", ev->e_incremental_update.processed, ev->e_incremental_update.updated, ev->e_incremental_update.removed, ev->e_incremental_update.added); break; case PKG_EVENT_DEBUG: fprintf(stderr, "DBG(%d)> %s\n", ev->e_debug.level, ev->e_debug.msg); break; default: break; } return 0; }
void source(int argc, char **argv) { struct stat stb; static BUF buffer; BUF *bp; off_t i, amt, statbytes; size_t result; int fd = -1, haderr, indx; char *last, *name, buf[2048]; int len; for (indx = 0; indx < argc; ++indx) { name = argv[indx]; statbytes = 0; len = strlen(name); while (len > 1 && name[len-1] == '/') name[--len] = '\0'; if (strchr(name, '\n') != NULL) { run_err("%s: skipping, filename contains a newline", name); goto next; } if ((fd = open(name, O_RDONLY, 0)) < 0) goto syserr; if (fstat(fd, &stb) < 0) { syserr: run_err("%s: %s", name, strerror(errno)); goto next; } switch (stb.st_mode & S_IFMT) { case S_IFREG: break; case S_IFDIR: if (iamrecursive) { rsource(name, &stb); goto next; } /* FALLTHROUGH */ default: run_err("%s: not a regular file", name); goto next; } if ((last = strrchr(name, '/')) == NULL) last = name; else ++last; curfile = last; if (pflag) { /* * Make it compatible with possible future * versions expecting microseconds. */ (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n", (u_long) stb.st_mtime, (u_long) stb.st_atime); (void) atomicio(vwrite, remout, buf, strlen(buf)); if (response() < 0) goto next; } #define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) snprintf(buf, sizeof buf, "C%04o %lld %s\n", (u_int) (stb.st_mode & FILEMODEMASK), (long long)stb.st_size, last); if (verbose_mode) { fprintf(stderr, "Sending file modes: %s", buf); } (void) atomicio(vwrite, remout, buf, strlen(buf)); if (response() < 0) goto next; if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) { next: if (fd != -1) { (void) close(fd); fd = -1; } continue; } #if PROGRESS_METER if (showprogress) start_progress_meter(curfile, stb.st_size, &statbytes); #endif /* Keep writing after an error so that we stay sync'd up. */ for (haderr = i = 0; i < stb.st_size; i += bp->cnt) { amt = bp->cnt; if (i + amt > stb.st_size) amt = stb.st_size - i; if (!haderr) { result = atomicio(read, fd, bp->buf, amt); if (result != amt) haderr = errno; } if (haderr) (void) atomicio(vwrite, remout, bp->buf, amt); else { result = atomicio(vwrite, remout, bp->buf, amt); if (result != amt) haderr = errno; statbytes += result; } } #ifdef PROGRESS_METER if (showprogress) stop_progress_meter(); #endif if (fd != -1) { if (close(fd) < 0 && !haderr) haderr = errno; fd = -1; } if (!haderr) (void) atomicio(vwrite, remout, "", 1); else run_err("%s: %s", name, strerror(haderr)); (void) response(); } }
/* * Download a package to the local cache. */ ssize_t download_pkg(char *pkg_url, FILE *fp) { struct url_stat st; size_t size, wrote; ssize_t fetched, written = 0; off_t statsize = 0; struct url *url; fetchIO *f = NULL; char buf[4096]; char *pkg, *ptr; if ((url = fetchParseURL(pkg_url)) == NULL) errx(EXIT_FAILURE, "%s: parse failure", pkg_url); if ((f = fetchXGet(url, &st, "")) == NULL) errx(EXIT_FAILURE, "%s: %s", pkg_url, fetchLastErrString); /* Package not available */ if (st.size == -1) return st.size; if ((pkg = strrchr(pkg_url, '/')) != NULL) pkg++; else pkg = (char *)pkg_url; /* should not happen */ if (parsable) { printf(MSG_DOWNLOAD_START); } else { printf(MSG_DOWNLOADING, pkg); fflush(stdout); start_progress_meter(pkg, st.size, &statsize); } while (written < st.size) { if ((fetched = fetchIO_read(f, buf, sizeof(buf))) == 0) break; if (fetched == -1 && errno == EINTR) continue; if (fetched == -1) errx(EXIT_FAILURE, "fetch failure: %s", fetchLastErrString); statsize += fetched; size = fetched; for (ptr = buf; size > 0; ptr += wrote, size -= wrote) { if ((wrote = fwrite(ptr, 1, size, fp)) < size) { if (ferror(fp) && errno == EINTR) clearerr(fp); else break; } written += wrote; } } if (parsable) printf(MSG_DOWNLOAD_END); else stop_progress_meter(); fetchIO_close(f); fetchFreeURL(url); if (written != st.size) return -1; return written; }
int event_callback(void *data, struct pkg_event *ev) { struct pkg *pkg = NULL; struct pkg_dep *dep = NULL; const char *message; int *debug = data; (void) debug; const char *name, *version, *newversion; const char *filename; struct pkg_event_conflict *cur_conflict; switch(ev->type) { case PKG_EVENT_ERRNO: warnx("%s(%s): %s", ev->e_errno.func, ev->e_errno.arg, strerror(ev->e_errno.no)); break; case PKG_EVENT_ERROR: warnx("%s", ev->e_pkg_error.msg); break; case PKG_EVENT_NOTICE: if (!quiet) warnx("%s", ev->e_pkg_notice.msg); break; case PKG_EVENT_DEVELOPER_MODE: warnx("DEVELOPER_MODE: %s", ev->e_pkg_error.msg); break; case PKG_EVENT_FETCHING: if (quiet || !isatty(fileno(stdin))) break; if (fetched == 0) { filename = strrchr(ev->e_fetching.url, '/'); if (filename != NULL) { filename++; } else { /* * We failed at being smart, so display * the entire url. */ filename = ev->e_fetching.url; } strlcpy(url, filename, sizeof(url)); start_progress_meter(url, ev->e_fetching.total, &fetched); } fetched = ev->e_fetching.done; if (ev->e_fetching.done == ev->e_fetching.total) { stop_progress_meter(); fetched = 0; } break; case PKG_EVENT_INSTALL_BEGIN: if (quiet) break; pkg_get(ev->e_install_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version); nbdone++; if (nbactions > 0) printf("[%d/%d] ", nbdone, nbactions); printf("Installing %s-%s...", name, version); /* print to the terminal title*/ printf("%c]0;[%d/%d] Installing %s-%s%c", '\033', nbdone, nbactions, name, version, '\007'); break; case PKG_EVENT_INSTALL_FINISHED: if (quiet) break; printf(" done\n"); pkg_get(ev->e_install_finished.pkg, PKG_MESSAGE, &message); if (message != NULL && message[0] != '\0') { if (messages == NULL) messages = sbuf_new_auto(); sbuf_printf(messages, "%s\n", message); } break; case PKG_EVENT_INTEGRITYCHECK_BEGIN: if (quiet) break; printf("Checking integrity..."); break; case PKG_EVENT_INTEGRITYCHECK_FINISHED: if (quiet) break; printf(" done\n"); break; case PKG_EVENT_INTEGRITYCHECK_CONFLICT: printf("\nConflict found on path %s between %s-%s(%s) and ", ev->e_integrity_conflict.pkg_path, ev->e_integrity_conflict.pkg_name, ev->e_integrity_conflict.pkg_version, ev->e_integrity_conflict.pkg_origin); cur_conflict = ev->e_integrity_conflict.conflicts; while (cur_conflict) { if (cur_conflict->next) printf("%s-%s(%s), ", cur_conflict->name, cur_conflict->version, cur_conflict->origin); else printf("%s-%s(%s)", cur_conflict->name, cur_conflict->version, cur_conflict->origin); cur_conflict = cur_conflict->next; } printf("\n"); break; case PKG_EVENT_DEINSTALL_BEGIN: if (quiet) break; pkg_get(ev->e_deinstall_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version); nbdone++; if (nbactions > 0) printf("[%d/%d] ", nbdone, nbactions); printf("Deleting %s-%s...", name, version); printf("%c]0;[%d/%d] Deleting %s-%s%c", '\033', nbdone, nbactions, name, version, '\007'); break; case PKG_EVENT_DEINSTALL_FINISHED: if (quiet) break; printf(" done\n"); break; case PKG_EVENT_UPGRADE_BEGIN: if (quiet) break; pkg_get(ev->e_upgrade_begin.pkg, PKG_NAME, &name, PKG_VERSION, &newversion, PKG_OLD_VERSION, &version); nbdone++; if (nbactions > 0) printf("[%d/%d] ", nbdone, nbactions); switch (pkg_version_cmp(version, newversion)) { case 1: printf("Downgrading %s from %s to %s...", name, version, newversion); printf("%c]0;[%d/%d] Downgrading %s from %s to %s%c", '\033', nbdone, nbactions, name, version, newversion, '\007'); break; case 0: printf("Reinstalling %s-%s", name, version); printf("%c]0;[%d/%d] Reinstalling %s-%s%c", '\033', nbdone, nbactions, name, version, '\007'); break; case -1: printf("Upgrading %s from %s to %s...", name, version, newversion); printf("%c]0;[%d/%d] Upgrading %s from %s to %s%c", '\033', nbdone, nbactions, name, version, newversion, '\007'); break; } break; case PKG_EVENT_UPGRADE_FINISHED: if (quiet) break; printf(" done\n"); break; case PKG_EVENT_LOCKED: pkg = ev->e_locked.pkg; pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version); fprintf(stderr, "\n%s-%s is locked and may not be modified\n", name, version); break; case PKG_EVENT_REQUIRED: pkg = ev->e_required.pkg; pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version); fprintf(stderr, "\n%s-%s is required by:", name, version); while (pkg_rdeps(pkg, &dep) == EPKG_OK) fprintf(stderr, " %s-%s", pkg_dep_name(dep), pkg_dep_version(dep)); if (ev->e_required.force == 1) fprintf(stderr, ", deleting anyway\n"); else fprintf(stderr, "\n"); break; case PKG_EVENT_ALREADY_INSTALLED: if (quiet) break; pkg_get(ev->e_already_installed.pkg, PKG_NAME, &name, PKG_VERSION, &version); printf("%s-%s already installed\n", name, version); break; case PKG_EVENT_NOT_FOUND: printf("Package '%s' was not found in " "the repositories\n", ev->e_not_found.pkg_name); break; case PKG_EVENT_MISSING_DEP: fprintf(stderr, "missing dependency %s-%s\n", pkg_dep_name(ev->e_missing_dep.dep), pkg_dep_version(ev->e_missing_dep.dep)); break; case PKG_EVENT_NOREMOTEDB: fprintf(stderr, "Unable to open remote database \"%s\". " "Try running '%s update' first.\n", ev->e_remotedb.repo, getprogname()); break; case PKG_EVENT_NOLOCALDB: fprintf(stderr, "Local package database nonexistent!\n"); break; case PKG_EVENT_NEWPKGVERSION: printf("New version of pkg detected; it needs to be " "installed first.\nAfter this upgrade it is recommended " "that you do a full upgrade using: 'pkg upgrade'\n\n"); break; case PKG_EVENT_FILE_MISMATCH: pkg_get(ev->e_file_mismatch.pkg, PKG_NAME, &name, PKG_VERSION, &version); fprintf(stderr, "%s-%s: checksum mismatch for %s\n", name, version, pkg_file_path(ev->e_file_mismatch.file)); break; case PKG_EVENT_PLUGIN_ERRNO: warnx("%s: %s(%s): %s", pkg_plugin_get(ev->e_plugin_errno.plugin, PKG_PLUGIN_NAME), ev->e_plugin_errno.func, ev->e_plugin_errno.arg, strerror(ev->e_plugin_errno.no)); break; case PKG_EVENT_PLUGIN_ERROR: warnx("%s: %s", pkg_plugin_get(ev->e_plugin_error.plugin, PKG_PLUGIN_NAME), ev->e_plugin_error.msg); break; case PKG_EVENT_PLUGIN_INFO: if (quiet) break; printf("%s: %s\n", pkg_plugin_get(ev->e_plugin_info.plugin, PKG_PLUGIN_NAME), ev->e_plugin_info.msg); break; case PKG_EVENT_INCREMENTAL_UPDATE: if (!quiet) printf("Incremental update completed, %d packages processed:\n" "%d packages updated, %d removed and %d added.\n", ev->e_incremental_update.processed, ev->e_incremental_update.updated, ev->e_incremental_update.removed, ev->e_incremental_update.added); break; default: break; } return 0; }
int event_callback(void *data, struct pkg_event *ev) { struct pkg *pkg = NULL; struct pkg_dep *dep = NULL; const char *message; int *debug = data; (void) debug; const char *name, *version, *newversion; const char *filename; switch(ev->type) { case PKG_EVENT_ERRNO: warn("%s(%s)", ev->e_errno.func, ev->e_errno.arg); break; case PKG_EVENT_ERROR: warnx("%s", ev->e_pkg_error.msg); break; case PKG_EVENT_FETCHING: if (quiet) break; if (fetched == 0) { filename = strrchr(ev->e_fetching.url, '/'); if (filename != NULL) { filename++; } else { /* * We failed at being smart, so display * the entire url. */ filename = ev->e_fetching.url; } strlcpy(url, filename, sizeof(url)); start_progress_meter(url, ev->e_fetching.total, &fetched); } fetched = ev->e_fetching.done; if (ev->e_fetching.done == ev->e_fetching.total) { stop_progress_meter(); fetched = 0; } break; case PKG_EVENT_INSTALL_BEGIN: if (quiet) break; pkg_get(ev->e_install_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version); printf("Installing %s-%s...", name, version); break; case PKG_EVENT_INSTALL_FINISHED: if (quiet) break; printf(" done\n"); pkg_get(ev->e_install_finished.pkg, PKG_MESSAGE, &message); if (message != NULL && message[0] != '\0') { if (messages == NULL) messages = sbuf_new_auto(); sbuf_printf(messages, "%s\n", message); } break; case PKG_EVENT_INTEGRITYCHECK_BEGIN: if (quiet) break; printf("Checking integrity..."); break; case PKG_EVENT_INTEGRITYCHECK_FINISHED: if (quiet) break; printf(" done\n"); break; case PKG_EVENT_DEINSTALL_BEGIN: if (quiet) break; pkg_get(ev->e_deinstall_begin.pkg, PKG_NAME, &name, PKG_VERSION, &version); printf("Deinstalling %s-%s...", name, version); break; case PKG_EVENT_DEINSTALL_FINISHED: if (quiet) break; printf(" done\n"); break; case PKG_EVENT_UPGRADE_BEGIN: if (quiet) break; pkg_get(ev->e_upgrade_finished.pkg, PKG_NAME, &name, PKG_VERSION, &version, PKG_NEWVERSION, &newversion); switch (pkg_version_cmp(version, newversion)) { case 1: printf("Downgrading %s from %s to %s...", name, version, newversion); break; case 0: printf("Reinstalling %s-%s", name, version); break; case -1: printf("Upgrading %s from %s to %s...", name, version, newversion); break; } break; case PKG_EVENT_UPGRADE_FINISHED: if (quiet) break; printf(" done\n"); break; case PKG_EVENT_REQUIRED: pkg = ev->e_required.pkg; pkg_get(pkg, PKG_NAME, &name, PKG_VERSION, &version); fprintf(stderr, "%s-%s is required by:", name, version); while (pkg_rdeps(pkg, &dep) == EPKG_OK) fprintf(stderr, " %s-%s", pkg_dep_name(dep), pkg_dep_version(dep)); if (ev->e_required.force == 1) fprintf(stderr, ", deleting anyway\n"); else fprintf(stderr, "\n"); break; case PKG_EVENT_ALREADY_INSTALLED: if (quiet) break; pkg_get(ev->e_already_installed.pkg, PKG_NAME, &name, PKG_VERSION, &version); printf("%s-%s already installed\n", name, version); break; case PKG_EVENT_MISSING_DEP: fprintf(stderr, "missing dependency %s-%s", pkg_dep_name(ev->e_missing_dep.dep), pkg_dep_version(ev->e_missing_dep.dep)); break; case PKG_EVENT_NOREMOTEDB: fprintf(stderr, "Unable to open remote database \"%s\". " "Try running '%s update' first.\n", ev->e_remotedb.repo, getprogname()); break; case PKG_EVENT_NOLOCALDB: /* only cares if run as root */ if (geteuid() == 0) fprintf(stderr, "Unable to create local database!\n"); break; case PKG_EVENT_NEWPKGVERSION: printf("New version of pkg detected; it needs to be " "installed first.\nAfter this upgrade it is recommended" "that you do a full upgrade using: 'pkg upgrade'\n\n"); break; case PKG_EVENT_FILE_MISMATCH: pkg_get(ev->e_file_mismatch.pkg, PKG_NAME, &name, PKG_VERSION, &version); fprintf(stderr, "%s-%s: checksum mismatch for %s\n", name, version, pkg_file_path(ev->e_file_mismatch.file)); default: break; } return 0; }