예제 #1
0
파일: ftpsend.c 프로젝트: sebastinas/yafc
/* abort routine originally from Cftp by Dieter Baron
 */
int ftp_abort(Socket* fp)
{
	char buf[4096];

#ifdef HAVE_LIBSSH
	if(ftp->session)
		/* FIXME: what? */
		return 0;
#endif

	if(!ftp_connected())
		return -1;

	ftp_set_close_handler();

	if (sock_check_pending(fp, false) == 1) {
		ftp_trace("There is data on the control channel, won't send ABOR\n");
		/* read remaining bytes from connection */
		while(fp && sock_read(fp, buf, sizeof(buf)) > 0)
			/* LOOP */ ;
		return 0;
	}

	ftp->ti.interrupted = true;
	ftp_err(_("Waiting for remote to finish abort...\n"));

	ftp_trace("--> telnet interrupt\n");
	if(sock_telnet_interrupt(ftp->ctrl) != 0)
		ftp_err("telnet interrupt: %s\n", strerror(errno));

	/* ftp_cmd("ABOR") won't work here,
	 * we must flush data between the ABOR command and ftp_read_reply()
	 */
	sock_krb_printf(ftp->ctrl, "ABOR");
	sock_printf(ftp->ctrl, "\r\n");
	sock_flush(ftp->ctrl);
	if(ftp_get_verbosity() == vbDebug)
		ftp_err("--> [%s] ABOR\n", ftp->url->hostname);
	else
		ftp_trace("--> [%s] ABOR\n", ftp->url->hostname);

    /* read remaining bytes from connection */
	while(fp && sock_read(fp, buf, sizeof(buf)) > 0)
		/* LOOP */ ;

	/* we expect a 426 or 226 reply here... */
	ftp_read_reply();
	if(ftp->fullcode != 426 && ftp->fullcode != 226)
		ftp_trace("Huh!? Expected a 426 or 226 reply\n");

	/* ... and a 226 or 225 reply here, respectively */
	/* FIXME: should skip this reply if prev. reply wasn't 426 or 226 ? */
	ftp_read_reply();
	if(ftp->fullcode != 226 && ftp->fullcode != 225)
		ftp_trace("Huh!? Expected a 226 or 225 reply\n");

	return -1;
}
예제 #2
0
파일: proto.c 프로젝트: abingham/ponyc
uint32_t proto_finish(proto_t* p)
{
  if(p == NULL || p->target == NULL)
    return 0;

  sock_bookmark_write(p->target, p->bookmark, &p->prefix.length,
    sizeof(p->prefix.length));

  return sock_flush(p->target);
}
예제 #3
0
파일: proto.c 프로젝트: abingham/ponyc
uint32_t proto_send(uint16_t header, sock_t* s)
{
  prefix_t prefix;

  prefix.header = (header | MAGIC);
  prefix.length = 0;

  sock_write(s, &prefix, sizeof(prefix.header));
  sock_write(s, &prefix.length, sizeof(prefix.length));

  return sock_flush(s);
}
예제 #4
0
파일: ftpsend.c 프로젝트: sebastinas/yafc
static int FILE_send_binary(FILE *in, Socket *out)
{
	time_t then = time(0) - 1;
	time_t now;

	ftp_set_close_handler();

	if(foo_hookf)
		foo_hookf(&ftp->ti);
	ftp->ti.begin = false;

	clearerr(in);
	sock_clearerr_out(out);

	char* buf = xmalloc(FTP_BUFSIZ);
	while(!feof(in)) {
		ssize_t n = fread(buf, sizeof(char), FTP_BUFSIZ, in);
		if(n <= 0)
			break;

		if(ftp_sigints() > 0)
			break;

		if(wait_for_output() != 0)
			break;

    if (sock_write(out, buf, n) != n)
      break;
		ftp->ti.size += n;
		if(foo_hookf) {
			now = time(0);
			if(now > then) {
				foo_hookf(&ftp->ti);
				then = now;
			}
		}
	}
	sock_flush(out);
	free(buf);

	return maybe_abort_out(in, out);
}
예제 #5
0
파일: ftp.c 프로젝트: casualuser/yafc
/* sends an FTP command on the control channel
 * returns reply status code on success or -1 on error
 */
int ftp_cmd(const char *cmd, ...)
{
    va_list ap;
    int resp;
    bool recon = false;

    if(!sock_connected(ftp->ctrl)) {
        ftp_err(_("No control connection\n"));
        ftp->code = ctNone;
        ftp->fullcode = -1;
        return -1;
    }

    ftp_set_abort_handler();

  ugly:

    va_start(ap, cmd);
    sock_krb_vprintf(ftp->ctrl, cmd, ap);
    sock_printf(ftp->ctrl, "\r\n");
    sock_flush(ftp->ctrl);
    va_end(ap);

    if(ferror(sock_sout(ftp->ctrl))) {
        ftp_err(_("error writing command"));
        ftp_err(" (");
        va_start(ap, cmd);
        vfprintf(stderr, cmd, ap);
        va_end(ap);
        va_start(ap, cmd);
        ftp_vtrace(cmd, ap);
        va_end(ap);
        ftp_err(")\n");
        ftp->code = ctNone;
        ftp->fullcode = -1;
        return -1;
    }

    va_start(ap, cmd);
    ftp_print_cmd(cmd, ap);
    va_end(ap);

    resp = ftp_read_reply();
    ftp_set_close_handler();
    if(resp == 421) { /* server is closing control connection! */
        ftp_err(_("Server closed control connection\n"));
        if(gvAutoReconnect && ftp_loggedin() && strcasecmp(cmd, "QUIT") != 0) {
            if(recon) {
                ftp_err(_("Reconnect failed\n"));
            } else {
                ftp_err(_("Automatic reconnect...\n"));
                ftp_reopen();
                recon = true;
                goto ugly;
            }
        } else {
            /*      ftp_close();*/
            ftp->fullcode = 421;
            ftp->code = 4;
            return -1;
        }
    }
    return resp;
}
예제 #6
0
파일: ftp.c 프로젝트: casualuser/yafc
/* reads one line from server into ftp->reply
 * returns 0 on success or -1 on failure
 */
static int ftp_gets(void)
{
    int c, i=0;

    ftp->reply[0] = 0;

    if(!sock_connected(ftp->ctrl)) {
        ftp_err(_("No control connection\n"));
        return -1;
    }

    while(true) {
        c = sock_get(ftp->ctrl);
        if(c == EOF) {
            ftp_err(_("Server has closed control connection\n"));
            ftp_close();
            return -1;
        }
        else if(c == 255/*IAC*/) {   /* handle telnet commands */
            switch(c = sock_get(ftp->ctrl)) {
              case 251/*WILL*/:
              case 252/*WONT*/:
                c = sock_get(ftp->ctrl);
                sock_printf(ftp->ctrl, "%c%c%c", 255/*IAC*/, 254/*DONT*/, c);
                sock_flush(ftp->ctrl);
                break;
              case 253/*DO*/:
              case 254/*DONT*/:
                c = sock_get(ftp->ctrl);
                sock_printf(ftp->ctrl, "%c%c%c", 255/*IAC*/, 252/*WONT*/, c);
                sock_flush(ftp->ctrl);
                break;
              default:
                break;
            }
            continue;
        }
        else if(c == '\r') {
            c = sock_get(ftp->ctrl);
            if(c == 0)
                c = '\r';
            else if(c == '\n') {
                ftp->reply[i++] = (char)c;
                break;
            } else if(c == EOF)
                /* do nothing */ ;
            else { /* telnet protocol violation, hmpf... */
                sock_unget(ftp->ctrl, c);
                continue;
            }
        }
        else if(c == '\n')
            break;
        if(i < MAXREPLY)
            ftp->reply[i++] = (char)c;
    }

    if(i >= MAXREPLY) {
        ftp_err(_("Reply too long (truncated)\n"));
        i = MAXREPLY;
    }

    ftp->reply[i] = '\0';
    ftp->fullcode = atoi(ftp->reply);
#ifdef SECFTP
    {
        int r = 0;
        switch(ftp->fullcode) { /* handle protected responses 6xx */
        case 631:
            r = sec_read_msg(ftp->reply, prot_safe);
            break;
        case 632:
            r = sec_read_msg(ftp->reply, prot_private);
            break;
        case 633:
            r = sec_read_msg(ftp->reply, prot_confidential);
            break;
        }
        if(r == -1) {
            ftp->fullcode = 0;
            ftp->code = vbNone;
            return 0;
        } else
            ftp->fullcode = atoi(ftp->reply);
    }
#endif
    strip_trailing_chars(ftp->reply, "\n\r");
    ftp->code = ftp->fullcode / 100;
    return ftp->fullcode;
}
예제 #7
0
int fflush_net(SOCKET *s)
{
	sock_flush(s);
	iferror return EOF;
	return 0;
}
예제 #8
0
파일: ftpsend.c 프로젝트: sebastinas/yafc
static int ftp_send(const char *path, FILE *fp, putmode_t how,
					transfer_mode_t mode, ftp_transfer_func hookf)
{
	int r;
	long rp = ftp->restart_offset;
	ftp->restart_offset = 0L;

	if(how == putUnique && !ftp->has_stou_command)
		return -1;

  if (how == putTryUnique && !ftp->has_stou_command)
    how = putNormal;

	reset_transfer_info();
	ftp->ti.transfer_is_put = true;

	if(ftp_init_transfer() != 0)
		return -1;

	ftp_type(mode);

	if(rp > 0) {
		/* fp is assumed to be fseek'd already */
		ftp_cmd("REST %ld", rp);
		if(ftp->code != ctContinue)
			return -1;
		ftp->ti.size = rp;
		ftp->ti.restart_size = rp;
	}

  ftp_set_tmp_verbosity(vbError);
  switch (how) {
  case putAppend:
    ftp_cmd("APPE %s", path);
    break;

  case putTryUnique:
  case putUnique:
    ftp_cmd("STOU %s", path);
    if (ftp->fullcode == 502 || ftp->fullcode == 504) {
      ftp->has_stou_command = false;
      if (how == putTryUnique)
        how = putNormal;
      else
        break;
    }
    else
      break;

  default:
    ftp_cmd("STOR %s", path);
    break;
  }

	if(ftp->code != ctPrelim)
		return -1;

	if(how == putUnique) {
		/* try to figure out remote filename */
		char *e = strstr(ftp->reply, " for ");
		if(e) {
			int l;
			e += 5;
			l = strlen(e);
			if(l) {
				free(ftp->ti.local_name);
				if(*e == '\'')
					ftp->ti.local_name = xstrndup(e+1, l-3);
				else
					ftp->ti.local_name = xstrndup(e, l-1);
				ftp_trace("parsed unique filename as '%s'\n",
						  ftp->ti.local_name);
			}
		}
	}

	if(!sock_accept(ftp->data, "w", ftp_is_passive())) {
		ftp_err(_("data connection not accepted\n"));
		return -1;
	}

	ftp_cache_flush_mark_for(path);

	if(mode == tmBinary)
		r = FILE_send_binary(fp, ftp->data);
	else
		r = FILE_send_ascii(fp, ftp->data);
	sock_flush(ftp->data);
	sock_destroy(ftp->data);
	ftp->data = 0;

	if(r == 0) {
		transfer_finished();
		ftp_read_reply();
		ftp->ti.ioerror = (ftp->code != ctComplete);
		if(ftp->code != ctComplete) {
			ftp_trace("transfer failed\n");
			return -1;
		}
	} else
		transfer_finished();

	return 0;
}
예제 #9
0
파일: ftpsend.c 프로젝트: wmene/yafc-1.1.2
/* abort routine originally from Cftp by Dieter Baron
 */
int ftp_abort(FILE *fp)
{
    char buf[4096];
    fd_set ready;
    struct timeval poll;

    if(ftp->ssh_pid)
        /* FIXME: what? */
        return 0;

    if(!ftp_connected())
        return -1;

    ftp_set_close_handler();

    poll.tv_sec = poll.tv_usec = 0;
    FD_ZERO(&ready);
    FD_SET(ftp->ctrl->handle, &ready);
    if(select(ftp->ctrl->handle+1, &ready, 0, 0, &poll) == 1) {
        ftp_trace("There is data on the control channel, won't send ABOR\n");
        /* read remaining bytes from connection */
        while(fp && fread(buf, 1, 4096, fp) > 0)
            /* LOOP */ ;
        return 0;
    }

    ftp->ti.interrupted = true;
    ftp_err(_("Waiting for remote to finish abort...\n"));

    ftp_trace("--> telnet interrupt\n");
    if(sock_telnet_interrupt(ftp->ctrl) != 0)
        ftp_err("telnet interrupt: %s\n", strerror(errno));

    /* ftp_cmd("ABOR") won't work here,
     * we must flush data between the ABOR command and ftp_read_reply()
     */
    sock_krb_printf(ftp->ctrl, "ABOR");
    sock_printf(ftp->ctrl, "\r\n");
    sock_flush(ftp->ctrl);
    if(ftp_get_verbosity() == vbDebug)
        ftp_err("--> [%s] ABOR\n", ftp->url->hostname);
    else
        ftp_trace("--> [%s] ABOR\n", ftp->url->hostname);

    /* read remaining bytes from connection */
    while(fp && fread(buf, 1, 4096, fp) > 0)
        /* LOOP */ ;

    /* we expect a 426 or 226 reply here... */
    ftp_read_reply();
    if(ftp->fullcode != 426 && ftp->fullcode != 226)
        ftp_trace("Huh!? Expected a 426 or 226 reply\n");

    /* ... and a 226 or 225 reply here, respectively */
    /* FIXME: should skip this reply if prev. reply wasn't 426 or 226 ? */
    ftp_read_reply();
    if(ftp->fullcode != 226 && ftp->fullcode != 225)
        ftp_trace("Huh!? Expected a 226 or 225 reply\n");

    return -1;
}