main.c
author Sunil Nimmagadda <sunil@nimmagadda.net>
Tue, 06 Dec 2022 13:51:55 +0000
changeset 0 1d0ce1ebbc72
permissions -rw-r--r--
An HTTP(S), FTP client. Found a copy of some old OpenBSD days hacking stashed somewhere in the backups. This version saw the light of the day as official OpenBSD ftp(1) for a grand total of 1 day :-)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     1
/*
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     2
 * Copyright (c) 2015 Sunil Nimmagadda <sunil@openbsd.org>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     3
 *
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     4
 * Permission to use, copy, modify, and distribute this software for any
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     5
 * purpose with or without fee is hereby granted, provided that the above
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     6
 * copyright notice and this permission notice appear in all copies.
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     7
 *
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     8
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
     9
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    10
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    11
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    12
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    13
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    14
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    15
 */
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    16
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    17
#include <sys/cdefs.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    18
#include <sys/types.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    19
#include <sys/queue.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    20
#include <sys/stat.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    21
#include <sys/socket.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    22
#include <sys/wait.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    23
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    24
#include <err.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    25
#include <errno.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    26
#include <fcntl.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    27
#include <imsg.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    28
#include <libgen.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    29
#include <signal.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    30
#include <stdio.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    31
#include <stdlib.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    32
#include <string.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    33
#include <unistd.h>
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    34
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    35
#include "ftp.h"
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    36
#include "xmalloc.h"
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    37
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    38
#define	IMSG_OPEN	 1
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    39
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    40
static int		 auto_fetch(int, char **);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    41
static void		 child(int, int, char **);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    42
static int		 parent(int, pid_t);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    43
static struct url	*proxy_parse(const char *);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    44
static int		 stdout_copy(const char *);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    45
static int		 append(const char *);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    46
static int		 save(const char *);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    47
static int		 slurp(struct url *, FILE *, off_t *, off_t);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    48
static char		*output_fname(struct url *, const char *);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    49
static void		 re_exec(int, int, char **);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    50
static __dead void	 usage(void);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    51
static int		 read_message(struct imsgbuf *, struct imsg *);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    52
static void		 send_message(struct imsgbuf *, int, uint32_t, void *,
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    53
			     size_t, int);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    54
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    55
struct url		*ftp_proxy, *http_proxy;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    56
const char		*useragent = "OpenBSD ftp";
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    57
char			*oarg;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    58
int			 activemode, family = AF_UNSPEC, io_debug;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    59
int			 progressmeter, verbose = 1;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    60
volatile sig_atomic_t	 interrupted = 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    61
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    62
static struct imsgbuf	 child_ibuf;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    63
static const char	*title;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    64
static char		*tls_options;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    65
static int		 connect_timeout, resume;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    66
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    67
int
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    68
main(int argc, char **argv)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    69
{
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    70
	const char	 *e;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    71
	char		**save_argv, *term;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    72
	int		  ch, csock, dumb_terminal, rexec, save_argc;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    73
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    74
	if (isatty(fileno(stdin)) != 1)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    75
		verbose = 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    76
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    77
	io_debug = getenv("IO_DEBUG") != NULL;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    78
	term = getenv("TERM");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    79
	dumb_terminal = (term == NULL || *term == '\0' ||
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    80
	    !strcmp(term, "dumb") || !strcmp(term, "emacs") ||
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    81
	    !strcmp(term, "su"));
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    82
	if (isatty(STDOUT_FILENO) && isatty(STDERR_FILENO) && !dumb_terminal)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    83
		progressmeter = 1;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    84
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    85
	csock = rexec = 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    86
	save_argc = argc;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    87
	save_argv = argv;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    88
	while ((ch = getopt(argc, argv,
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    89
	    "46AaCc:dD:Eegik:MmN:no:pP:r:S:s:tU:vVw:xz:")) != -1) {
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    90
		switch (ch) {
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    91
		case '4':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    92
			family = AF_INET;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    93
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    94
		case '6':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    95
			family = AF_INET6;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    96
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    97
		case 'A':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    98
			activemode = 1;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
    99
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   100
		case 'C':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   101
			resume = 1;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   102
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   103
		case 'D':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   104
			title = optarg;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   105
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   106
		case 'o':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   107
			oarg = optarg;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   108
			if (!strlen(oarg))
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   109
				oarg = NULL;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   110
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   111
		case 'M':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   112
			progressmeter = 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   113
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   114
		case 'm':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   115
			progressmeter = 1;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   116
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   117
		case 'N':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   118
			setprogname(optarg);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   119
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   120
		case 'S':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   121
			tls_options = optarg;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   122
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   123
		case 'U':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   124
			useragent = optarg;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   125
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   126
		case 'V':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   127
			verbose = 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   128
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   129
		case 'v':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   130
			verbose = 1;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   131
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   132
		case 'w':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   133
			connect_timeout = strtonum(optarg, 0, 200, &e);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   134
			if (e)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   135
				errx(1, "-w: %s", e);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   136
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   137
		/* options for internal use only */
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   138
		case 'x':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   139
			rexec = 1;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   140
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   141
		case 'z':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   142
			csock = strtonum(optarg, 3, getdtablesize() - 1, &e);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   143
			if (e)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   144
				errx(1, "-z: %s", e);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   145
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   146
		/* Ignoring all remaining options */
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   147
		case 'a':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   148
		case 'c':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   149
		case 'd':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   150
		case 'E':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   151
		case 'e':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   152
		case 'g':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   153
		case 'i':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   154
		case 'k':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   155
		case 'n':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   156
		case 'P':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   157
		case 'p':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   158
		case 'r':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   159
		case 's':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   160
		case 't':
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   161
			warnx("Ignoring getopt: %c", ch);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   162
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   163
		default:
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   164
			usage();
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   165
		}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   166
	}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   167
	argc -= optind;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   168
	argv += optind;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   169
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   170
	if (rexec)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   171
		child(csock, argc, argv);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   172
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   173
#ifndef SMALL
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   174
	struct url	*url;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   175
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   176
	switch (argc) {
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   177
	case 0:
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   178
		cmd(NULL, NULL, NULL);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   179
		return 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   180
	case 1:
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   181
	case 2:
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   182
		switch (url_scheme_lookup(argv[0])) {
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   183
		case -1:
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   184
			cmd(argv[0], argv[1], NULL);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   185
			return 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   186
		case S_FTP:
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   187
			url = xurl_parse(argv[0]);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   188
			if (url->path &&
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   189
			    url->path[strlen(url->path) - 1] != '/')
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   190
				break; /* auto fetch */
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   191
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   192
			cmd(url->host, url->port, url->path);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   193
			return 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   194
		}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   195
		break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   196
	}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   197
#else
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   198
	if (argc == 0)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   199
		usage();
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   200
#endif /* SMALL */
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   201
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   202
	return auto_fetch(save_argc, save_argv);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   203
}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   204
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   205
static int
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   206
auto_fetch(int sargc, char **sargv)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   207
{
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   208
	pid_t	pid;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   209
	int	sp[2];
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   210
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   211
	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, sp) != 0)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   212
		err(1, "socketpair");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   213
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   214
	switch (pid = fork()) {
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   215
	case -1:
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   216
		err(1, "fork");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   217
	case 0:
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   218
		close(sp[0]);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   219
		re_exec(sp[1], sargc, sargv);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   220
	}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   221
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   222
	close(sp[1]);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   223
	return parent(sp[0], pid);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   224
}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   225
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   226
static void
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   227
re_exec(int sock, int argc, char **argv)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   228
{
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   229
	char	**nargv, *sock_str;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   230
	int	  i, j, nargc;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   231
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   232
	nargc = argc + 4;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   233
	nargv = xcalloc(nargc, sizeof(*nargv));
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   234
	xasprintf(&sock_str, "%d", sock);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   235
	i = 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   236
	nargv[i++] = argv[0];
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   237
	nargv[i++] = "-z";
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   238
	nargv[i++] = sock_str;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   239
	nargv[i++] = "-x";
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   240
	for (j = 1; j < argc; j++)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   241
		nargv[i++] = argv[j];
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   242
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   243
	execvp(nargv[0], nargv);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   244
	err(1, "execvp");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   245
}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   246
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   247
static int
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   248
parent(int sock, pid_t child_pid)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   249
{
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   250
	struct imsgbuf	ibuf;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   251
	struct imsg	imsg;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   252
	struct stat	sb;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   253
	off_t		offset;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   254
	int		fd, save_errno, sig, status;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   255
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   256
	setproctitle("%s", "parent");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   257
	if (pledge("stdio cpath rpath wpath sendfd", NULL) == -1)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   258
		err(1, "pledge");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   259
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   260
	imsg_init(&ibuf, sock);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   261
	for (;;) {
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   262
		if (read_message(&ibuf, &imsg) == 0)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   263
			break;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   264
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   265
		if (imsg.hdr.type != IMSG_OPEN)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   266
			errx(1, "%s: IMSG_OPEN expected", __func__);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   267
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   268
		offset = 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   269
		fd = open(imsg.data, imsg.hdr.peerid, 0666);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   270
		save_errno = errno;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   271
		if (fd != -1 && fstat(fd, &sb) == 0) {
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   272
			if (sb.st_mode & S_IFDIR) {
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   273
				close(fd);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   274
				fd = -1;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   275
				save_errno = EISDIR;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   276
			} else
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   277
				offset = sb.st_size;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   278
		}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   279
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   280
		send_message(&ibuf, IMSG_OPEN, save_errno,
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   281
		    &offset, sizeof offset, fd);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   282
		imsg_free(&imsg);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   283
	}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   284
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   285
	close(sock);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   286
	if (waitpid(child_pid, &status, 0) == -1 && errno != ECHILD)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   287
		err(1, "wait");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   288
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   289
	sig = WTERMSIG(status);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   290
	if (WIFSIGNALED(status) && sig != SIGPIPE)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   291
		errx(1, "child terminated: signal %d", sig);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   292
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   293
	return WEXITSTATUS(status);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   294
}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   295
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   296
static void
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   297
child(int sock, int argc, char **argv)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   298
{
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   299
	int	i, to_stdout = 0, r = 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   300
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   301
	setproctitle("%s", "child");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   302
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   303
#ifndef NOSSL
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   304
	/*
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   305
	 * TLS can't be init-ed on first use as filesystem(ca file) isn't
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   306
	 * available after pledge(2).
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   307
	 */
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   308
	https_init(tls_options);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   309
#endif /* NOSSL */
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   310
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   311
	if (pledge("stdio inet dns recvfd tty unveil", NULL) == -1)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   312
		err(1, "pledge");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   313
	if (!progressmeter &&
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   314
	    pledge("stdio inet dns recvfd unveil", NULL) == -1)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   315
		err(1, "pledge");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   316
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   317
	imsg_init(&child_ibuf, sock);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   318
	ftp_proxy = proxy_parse("ftp_proxy");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   319
	http_proxy = proxy_parse("http_proxy");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   320
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   321
	if (oarg) {
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   322
		if (strcmp(oarg, "-") == 0) {
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   323
			to_stdout = 1;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   324
			if (resume)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   325
				errx(1, "can't append to stdout");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   326
		} else if (unveil(oarg, "w") == -1)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   327
			err(1, "unveil");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   328
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   329
		if (unveil(NULL, NULL) == -1)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   330
			err(1, "unveil");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   331
	}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   332
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   333
	for (i = 0; i < argc; i++) {
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   334
		if (to_stdout)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   335
			r = stdout_copy(argv[i]);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   336
		else if (resume)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   337
			r = append(argv[i]);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   338
		else
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   339
			r = save(argv[i]);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   340
	}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   341
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   342
	exit(r);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   343
}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   344
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   345
static int
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   346
stdout_copy(const char *arg)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   347
{
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   348
	struct url	*url;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   349
	off_t		 offset = 0, sz = 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   350
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   351
	url = xurl_parse(arg);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   352
	url_connect(url, connect_timeout);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   353
	url = url_request(url, &offset, &sz);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   354
	return slurp(url, stdout, &offset, sz);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   355
}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   356
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   357
static int
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   358
append(const char *arg)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   359
{
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   360
	struct url	*url;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   361
	FILE		*fp;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   362
	char		*fname;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   363
	off_t		 offset = 0, sz = 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   364
	int		 fd;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   365
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   366
	url = xurl_parse(arg);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   367
	url_connect(url, connect_timeout);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   368
	fname = output_fname(url, arg);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   369
	fd = fd_request(fname, O_WRONLY|O_APPEND, &offset);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   370
	url = url_request(url, &offset, &sz);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   371
	/* If HTTP server doesn't support range requests, truncate. */
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   372
	if (fd != -1 && offset == 0)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   373
		if (ftruncate(fd, 0) != 0)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   374
			err(1, "ftruncate");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   375
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   376
	if (fd == -1 &&
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   377
	    (fd = fd_request(fname, O_CREAT|O_TRUNC|O_WRONLY, NULL)) == -1)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   378
		err(1, "Can't open file %s", fname);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   379
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   380
	if ((fp = fdopen(fd, "w")) == NULL)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   381
		err(1, "%s: fdopen", __func__);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   382
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   383
	return slurp(url, fp, &offset, sz);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   384
}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   385
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   386
static int
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   387
save(const char *arg)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   388
{
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   389
	struct url	*url;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   390
	FILE		*fp;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   391
	char		*fname;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   392
	off_t		 offset = 0, sz = 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   393
	int		 fd, r;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   394
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   395
	url = xurl_parse(arg);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   396
	url_connect(url, connect_timeout);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   397
	url = url_request(url, &offset, &sz);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   398
	fname = output_fname(url, arg);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   399
	if ((fd = fd_request(fname, O_CREAT|O_TRUNC|O_WRONLY, NULL)) == -1)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   400
		err(1, "Can't open file %s", fname);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   401
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   402
	if ((fp = fdopen(fd, "w")) == NULL)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   403
		err(1, "%s: fdopen", __func__);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   404
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   405
	return slurp(url, fp, &offset, sz);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   406
}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   407
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   408
static int
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   409
slurp(struct url *url, FILE *fp, off_t *offset, off_t sz)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   410
{
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   411
	start_progress_meter(basename(url->path), title, sz, offset);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   412
	url_save(url, fp, offset);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   413
	stop_progress_meter();
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   414
	url_close(url);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   415
	url_free(url);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   416
	if (fp != stdout)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   417
		fclose(fp);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   418
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   419
	if (sz != 0 && *offset != sz) {
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   420
		log_info("Read short file\n");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   421
		return 1;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   422
	}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   423
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   424
	return 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   425
}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   426
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   427
static char *
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   428
output_fname(struct url *url, const char *arg)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   429
{
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   430
	char	*fname;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   431
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   432
	fname = oarg ? oarg : basename(url->path);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   433
	if (strcmp(fname, "/") == 0)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   434
		errx(1, "No filename after host (use -o): %s", arg);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   435
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   436
	if (strcmp(fname, ".") == 0)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   437
		errx(1, "No '/' after host (use -o): %s", arg);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   438
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   439
	return fname;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   440
}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   441
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   442
int
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   443
fd_request(char *path, int flags, off_t *offset)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   444
{
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   445
	struct imsg	 imsg;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   446
	off_t		*poffset;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   447
	int		 fd, save_errno;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   448
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   449
	send_message(&child_ibuf, IMSG_OPEN, flags, path, strlen(path) + 1, -1);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   450
	if (read_message(&child_ibuf, &imsg) == 0)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   451
		return -1;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   452
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   453
	if (imsg.hdr.type != IMSG_OPEN)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   454
		errx(1, "%s: IMSG_OPEN expected", __func__);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   455
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   456
	fd = imsg.fd;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   457
	if (offset) {
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   458
		poffset = imsg.data;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   459
		*offset = *poffset;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   460
	}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   461
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   462
	save_errno = imsg.hdr.peerid;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   463
	imsg_free(&imsg);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   464
	errno = save_errno;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   465
	return fd;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   466
}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   467
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   468
void
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   469
send_message(struct imsgbuf *ibuf, int type, uint32_t peerid,
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   470
    void *msg, size_t msglen, int fd)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   471
{
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   472
	if (imsg_compose(ibuf, type, peerid, 0, fd, msg, msglen) != 1)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   473
		err(1, "imsg_compose");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   474
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   475
	if (imsg_flush(ibuf) != 0)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   476
		err(1, "imsg_flush");
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   477
}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   478
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   479
int
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   480
read_message(struct imsgbuf *ibuf, struct imsg *imsg)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   481
{
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   482
	int	n;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   483
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   484
	if ((n = imsg_read(ibuf)) == -1)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   485
		err(1, "%s: imsg_read", __func__);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   486
	if (n == 0)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   487
		return 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   488
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   489
	if ((n = imsg_get(ibuf, imsg)) == -1)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   490
		err(1, "%s: imsg_get", __func__);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   491
	if (n == 0)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   492
		return 0;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   493
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   494
	return n;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   495
}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   496
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   497
static struct url *
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   498
proxy_parse(const char *name)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   499
{
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   500
	struct url	*proxy;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   501
	char		*str;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   502
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   503
	if ((str = getenv(name)) == NULL)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   504
		return NULL;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   505
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   506
	if (strlen(str) == 0)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   507
		return NULL;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   508
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   509
	proxy = xurl_parse(str);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   510
	if (proxy->scheme != S_HTTP)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   511
		errx(1, "Malformed proxy URL: %s", str);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   512
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   513
	return proxy;
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   514
}
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   515
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   516
static __dead void
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   517
usage(void)
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   518
{
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   519
	fprintf(stderr,
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   520
	    "usage:\t%s [-46AVv] [-D title] [host [port]]\n"
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   521
	    "\t%s [-46ACVMmVv] [-N name] [-D title] [-o output]\n"
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   522
	    "\t\t [-S tls_options] [-U useragent] [-w seconds] url ...\n",
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   523
	    getprogname(), getprogname());
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   524
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   525
	exit(1);
1d0ce1ebbc72 An HTTP(S), FTP client.
Sunil Nimmagadda <sunil@nimmagadda.net>
parents:
diff changeset
   526
}