Example #1
0
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;
}
Example #2
0
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();
}
Example #3
0
/*
 * 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;
}
Example #4
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;

	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;
}
Example #5
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);
	}
}
Example #6
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);
}
Example #7
0
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();
	}
}
Example #8
0
/* 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;
}
Example #9
0
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;
}
Example #10
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();
	}
}
Example #11
0
/*
 * 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;
}
Example #12
0
File: event.c Project: afb/pkgng
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;
}
Example #13
0
File: event.c Project: gsamat/pkgng
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;
}