Exemplo n.º 1
0
static int FtpOpenPort(struct stream_priv_s* p) {
  int resp,fd;
  char rsp_txt[256];
  char* par,str[128];
  int num[6];

  resp = FtpSendCmd("PASV",p,rsp_txt);
  if(resp != 2) {
    mp_msg(MSGT_OPEN,MSGL_WARN, "[ftp] command 'PASV' failed: %s\n",rsp_txt);
    return 0;
  }
  
  par = strchr(rsp_txt,'(');
  
  if(!par || !par[0] || !par[1]) {
    mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] invalid server response: %s ??\n",rsp_txt);
    return 0;
  }

  sscanf(par+1,"%u,%u,%u,%u,%u,%u",&num[0],&num[1],&num[2],
	 &num[3],&num[4],&num[5]);
  snprintf(str,127,"%d.%d.%d.%d",num[0],num[1],num[2],num[3]);
  fd = connect2Server(str,(num[4]<<8)+num[5],0);

  if(fd < 0)
    mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] failed to create data connection\n");

  return fd;
}
Exemplo n.º 2
0
/*
 * FtpLogin - log in to remote server
 *
 * return 1 if logged in, 0 otherwise
 */
GLOBALDEF int FtpLogin(const char *user, const char *pass, netbuf *nControl)
{
	char tempbuf[64];

	if (((strlen(user) + 7) > sizeof(tempbuf)) ||
			((strlen(pass) + 7) > sizeof(tempbuf)))
		return 0;
	sprintf(tempbuf,"USER %s",user);
	if (!FtpSendCmd(tempbuf,'3',nControl))
	{
		if (nControl->response[0] == '2')
			return 1;
		return 0;
	}
	sprintf(tempbuf,"PASS %s",pass);
	return FtpSendCmd(tempbuf,'2',nControl);
}
Exemplo n.º 3
0
/*
 * FtpQuit - disconnect from remote
 *
 * return 1 if successful, 0 otherwise
 */
GLOBALDEF void FtpQuit (netbuf *nControl) {
    if (nControl->dir != FTPLIB_CONTROL)
        return;
    FtpSendCmd("QUIT", '2', nControl);
    net_close(nControl->handle);
    free(nControl->buf);
    free(nControl);
}
Exemplo n.º 4
0
/*
 * FtpRmdir - remove directory at remote
 *
 * return 1 if successful, 0 otherwise
 */
GLOBALDEF int FtpRmdir (const char *path, netbuf *nControl) {
    char buf[256];

    if ((strlen(path) + 6) > sizeof (buf))
        return 0;
    sprintf(buf, "RMD %s", path);
    if (!FtpSendCmd(buf, '2', nControl))
        return 0;
    return 1;
}
Exemplo n.º 5
0
/*
 * FtpDelete - delete a file at remote
 *
 * return 1 if successful, 0 otherwise
 */
GLOBALDEF int FtpDelete (const char *fnm, netbuf *nControl) {
    char cmd[256];

    if ((strlen(fnm) + 7) > sizeof (cmd))
        return 0;
    sprintf(cmd, "DELE %s", fnm);
    if (!FtpSendCmd(cmd, '2', nControl))
        return 0;
    return 1;
}
Exemplo n.º 6
0
/*
 * FtpRestart - issue a REST command
 *
 * return 1 if successful, 0 otherwise
 */
GLOBALDEF int FtpRestart(int offset, netbuf *nControl)
{
	char cmd[256];
	int rv=1;

	sprintf(cmd,"REST %d",offset);
	if (!FtpSendCmd(cmd,'3',nControl))
		rv = 0;
	return rv;
}
Exemplo n.º 7
0
/*
 * FtpSite - send a SITE command
 *
 * return 1 if command successful, 0 otherwise
 */
GLOBALDEF int FtpSite (const char *cmd, netbuf *nControl) {
    char buf[256];

    if ((strlen(cmd) + 7) > sizeof (buf))
        return 0;
    sprintf(buf, "SITE %s", cmd);
    if (!FtpSendCmd(buf, '2', nControl))
        return 0;
    return 1;
}
Exemplo n.º 8
0
/*
 * FtpSize - determine the size of a remote file
 *
 * return 1 if successful, 0 otherwise
 */
GLOBALDEF int FtpSize (const char *path, int *size, char mode, netbuf *nControl) {
    char cmd[256];
    int resp, sz, rv = 1;

    if ((strlen(path) + 7) > sizeof (cmd))
        return 0;
    sprintf(cmd, "TYPE %c", mode);
    if (!FtpSendCmd(cmd, '2', nControl))
        return 0;
    sprintf(cmd, "SIZE %s", path);
    if (!FtpSendCmd(cmd, '2', nControl))
        rv = 0;
    else {
        if (sscanf(nControl->response, "%d %d", &resp, &sz) == 2)
            *size = sz;
        else
            rv = 0;
    }
    return rv;
}
Exemplo n.º 9
0
static int seek(stream_t *s,off_t newpos) {
  struct stream_priv_s* p = s->priv;
  int resp;
  char rsp_txt[256];

  if(s->pos > s->end_pos) {
    s->eof=1;
    return 0;
  }

  // Check to see if the server did not already terminate the transfer
  if(fd_can_read(p->handle, 0)) {
    if(readresp(p,rsp_txt) != 2)
      mp_msg(MSGT_OPEN,MSGL_WARN, "[ftp] Warning the server didn't finished the transfer correctly: %s\n",rsp_txt);
    closesocket(s->fd);
    s->fd = -1;
  }

  // Close current download
  if(s->fd >= 0) {
    static const char pre_cmd[]={TELNET_IAC,TELNET_IP,TELNET_IAC,TELNET_SYNCH};
    //int fl;
    
    // First close the fd
    closesocket(s->fd);
    s->fd = 0;
    
    // Send send the telnet sequence needed to make the server react
    
    // Dunno if this is really needed, lftp have it. I let
    // it here in case it turn out to be needed on some other OS
    //fl=fcntl(p->handle,F_GETFL);
    //fcntl(p->handle,F_SETFL,fl&~O_NONBLOCK);

    // send only first byte as OOB due to OOB braindamage in many unices
    send(p->handle,pre_cmd,1,MSG_OOB);
    send(p->handle,pre_cmd+1,sizeof(pre_cmd)-1,0);
    
    //fcntl(p->handle,F_SETFL,fl);

    // Get the 426 Transfer aborted
    // Or the 226 Transfer complete
    resp = readresp(p,rsp_txt);
    if(resp != 4 && resp != 2) {
      mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] Server didn't abort correctly: %s\n",rsp_txt);
      s->eof = 1;
      return 0;
    }
    // Send the ABOR command
    // Ignore the return code as sometimes it fail with "nothing to abort"
    FtpSendCmd("ABOR",p,rsp_txt);
  }
  return FtpOpenData(s,newpos);
}
Exemplo n.º 10
0
/*
 * FtpSysType - send a SYST command
 *
 * Fills in the user buffer with the remote system type.  If more
 * information from the response is required, the user can parse
 * it out of the response buffer returned by FtpLastResponse().
 *
 * return 1 if command successful, 0 otherwise
 */
GLOBALDEF int FtpSysType (char *buf, int max, netbuf *nControl) {
    int l = max;
    char *b = buf;
    char *s;
    if (!FtpSendCmd("SYST", '2', nControl))
        return 0;
    s = &nControl->response[4];
    while ((--l) && (*s != ' '))
        *b++ = *s++;
    *b++ = '\0';
    return 1;
}
Exemplo n.º 11
0
/*
 * FtpModDate - determine the modification date of a remote file
 *
 * return 1 if successful, 0 otherwise
 */
GLOBALDEF int FtpModDate (const char *path, char *dt, int max, netbuf *nControl) {
    char buf[256];
    int rv = 1;

    if ((strlen(path) + 7) > sizeof (buf))
        return 0;
    sprintf(buf, "MDTM %s", path);
    if (!FtpSendCmd(buf, '2', nControl))
        rv = 0;
    else
        strncpy(dt, &nControl->response[4], max);
    return rv;
}
Exemplo n.º 12
0
/*
 * FtpPwd - get working directory at remote
 *
 * return 1 if successful, 0 otherwise
 */
GLOBALDEF int FtpPwd (char *path, int max, netbuf *nControl) {
    int l = max;
    char *b = path;
    char *s;
    if (!FtpSendCmd("PWD", '2', nControl))
        return 0;
    s = strchr(nControl->response, '"');
    if (s == NULL)
        return 0;
    s++;
    while ((--l) && (*s) && (*s != '"'))
        *b++ = *s++;
    *b++ = '\0';
    return 1;
}
Exemplo n.º 13
0
static void close_f(stream_t *s) {
  struct stream_priv_s* p = s->priv;

  if(!p) return;

  if(s->fd > 0) {
    closesocket(s->fd);
    s->fd = 0;
  }

  FtpSendCmd("QUIT",p,NULL);

  if(p->handle) closesocket(p->handle);
  if(p->buf) free(p->buf);

  m_struct_free(&stream_opts,p);
}
Exemplo n.º 14
0
static int FtpSendCmd(const char *cmd, struct stream_priv_s *nControl,char* rsp)
{
  int l = strlen(cmd);
  int hascrlf = cmd[l - 2] == '\r' && cmd[l - 1] == '\n';

  if(hascrlf && l == 2) mp_msg(MSGT_STREAM,MSGL_V, "\n");
  else mp_msg(MSGT_STREAM,MSGL_V, "[ftp] > %s",cmd);
  while(l > 0) {
    int s = send(nControl->handle,cmd,l,0);

    if(s <= 0) {
      mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] write error: %s\n",strerror(errno));
      return 0;
    }
    
    cmd += s;
    l -= s;
  }
    
  if (hascrlf)  
    return readresp(nControl,rsp);
  else
    return FtpSendCmd("\r\n", nControl, rsp);
}
Exemplo n.º 15
0
/*
 * FtpAccess - return a handle for a data stream
 *
 * return 1 if successful, 0 otherwise
 */
GLOBALDEF int FtpAccess(const char *path, int typ, int mode, netbuf *nControl,
		netbuf **nData)
{
	char buf[256];
	int dir;
	if ((path == NULL) &&
			((typ == FTPLIB_FILE_WRITE) || (typ == FTPLIB_FILE_READ)))
	{
		sprintf(nControl->response,
				"Missing path argument for file transfer\n");
		return 0;
	}
	sprintf(buf, "TYPE %c", mode);
	if (!FtpSendCmd(buf, '2', nControl))
		return 0;
	switch (typ)
	{
		case FTPLIB_DIR:
			strcpy(buf,"NLST");
			dir = FTPLIB_READ;
			break;
		case FTPLIB_DIR_VERBOSE:
			strcpy(buf,"LIST");
			dir = FTPLIB_READ;
			break;
		case FTPLIB_FILE_READ:
			strcpy(buf,"RETR");
			dir = FTPLIB_READ;
			break;
		case FTPLIB_FILE_WRITE:
			strcpy(buf,"STOR");
			dir = FTPLIB_WRITE;
			break;
		default:
			sprintf(nControl->response, "Invalid open type %d\n", typ);
			return 0;
	}
	if (path != NULL)
	{
		int i = strlen(buf);
		buf[i++] = ' ';
		if ((strlen(path) + i) >= sizeof(buf))
			return 0;
		strcpy(&buf[i],path);
	}
	if (FtpOpenPort(nControl, nData, mode, dir) == -1)
		return 0;
	if (!FtpSendCmd(buf, '1', nControl))
	{
		FtpClose(*nData);
		*nData = NULL;
		return 0;
	}
	(*nData)->ctrl = nControl;
	nControl->data = *nData;
	if (nControl->cmode == FTPLIB_PORT)
	{
		if (!FtpAcceptConnection(*nData,nControl))
		{
			FtpClose(*nData);
			*nData = NULL;
			nControl->data = NULL;
			return 0;
		}
	}
	return 1;
}
Exemplo n.º 16
0
static int open_f(stream_t *stream,int mode, void* opts, int* file_format) {
  int len = 0,resp;
  struct stream_priv_s* p = (struct stream_priv_s*)opts;
  char str[256],rsp_txt[256];

  if(mode != STREAM_READ) {
    mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] Unknown open mode %d\n",mode);
    m_struct_free(&stream_opts,opts);
    return STREAM_UNSUPPORTED;
  }

  if(!p->filename || !p->host) {
    mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] Bad url\n");
    m_struct_free(&stream_opts,opts);
    return STREAM_ERROR;
  }

  // Open the control connection
  p->handle = connect2Server(p->host,p->port,1);
  
  if(p->handle < 0) {
    m_struct_free(&stream_opts,opts);
    return STREAM_ERROR;
  }

  // We got a connection, let's start serious things
  stream->fd = -1;
  stream->priv = p;
  p->buf = malloc(BUFSIZE);

  if (readresp(p, NULL) == 0) {
    close_f(stream);
    m_struct_free(&stream_opts,opts);
    return STREAM_ERROR;
  }

  // Login
  snprintf(str,255,"USER %s",p->user);
  resp = FtpSendCmd(str,p,rsp_txt);

  // password needed
  if(resp == 3) {
    snprintf(str,255,"PASS %s",p->pass);
    resp = FtpSendCmd(str,p,rsp_txt);
    if(resp != 2) {
      mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] command '%s' failed: %s\n",str,rsp_txt);
      close_f(stream);
      return STREAM_ERROR;
    }
  } else if(resp != 2) {
    mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] command '%s' failed: %s\n",str,rsp_txt);
    close_f(stream);
    return STREAM_ERROR;
  }
    
  // Set the transfer type
  resp = FtpSendCmd("TYPE I",p,rsp_txt);
  if(resp != 2) {
    mp_msg(MSGT_OPEN,MSGL_WARN, "[ftp] command 'TYPE I' failed: %s\n",rsp_txt);
    close_f(stream);
    return STREAM_ERROR;
  }

  // Get the filesize
  snprintf(str,255,"SIZE %s",p->filename);
  resp = FtpSendCmd(str,p,rsp_txt);
  if(resp != 2) {
    mp_msg(MSGT_OPEN,MSGL_WARN, "[ftp] command '%s' failed: %s\n",str,rsp_txt);
  } else {
    int dummy;
    sscanf(rsp_txt,"%d %d",&dummy,&len);
  }

  if(len > 0) {
    stream->seek = seek;
    stream->end_pos = len;
  }

  // The data connection is really opened only at the first
  // read/seek. This must be done when the cache is used
  // because the connection would stay open in the main process,
  // preventing correct abort with many servers.
  stream->fd = -1;
  stream->priv = p;
  stream->fill_buffer = fill_buffer;
  stream->close = close_f;

  return STREAM_OK;
}
Exemplo n.º 17
0
/*
 * FtpOpenPort - set up data connection
 *
 * return 1 if successful, 0 otherwise
 */
static int FtpOpenPort(netbuf *nControl, netbuf **nData, int mode, int dir)
{
	int sData;
	union {
		struct sockaddr sa;
		struct sockaddr_in in;
	} sin;
	struct linger lng = { 0, 0 };
	unsigned int l;
	int on=1;
	netbuf *ctrl;
	char *cp;
	unsigned int v[6];
	char buf[256];

	if (nControl->dir != FTPLIB_CONTROL)
		return -1;
	if ((dir != FTPLIB_READ) && (dir != FTPLIB_WRITE))
	{
		sprintf(nControl->response, "Invalid direction %d\n", dir);
		return -1;
	}
	if ((mode != FTPLIB_ASCII) && (mode != FTPLIB_IMAGE))
	{
		sprintf(nControl->response, "Invalid mode %c\n", mode);
		return -1;
	}
	l = sizeof(sin);
	if (nControl->cmode == FTPLIB_PASSIVE)
	{
		memset(&sin, 0, l);
		sin.in.sin_family = AF_INET;
		if (!FtpSendCmd("PASV",'2',nControl))
			return -1;
		cp = strchr(nControl->response,'(');
		if (cp == NULL)
			return -1;
		cp++;
		sscanf(cp,"%u,%u,%u,%u,%u,%u",&v[2],&v[3],&v[4],&v[5],&v[0],&v[1]);
		sin.sa.sa_data[2] = v[2];
		sin.sa.sa_data[3] = v[3];
		sin.sa.sa_data[4] = v[4];
		sin.sa.sa_data[5] = v[5];
		sin.sa.sa_data[0] = v[0];
		sin.sa.sa_data[1] = v[1];
	}
	else
	{
		if (getsockname(nControl->handle, &sin.sa, &l) < 0)
		{
			perror("getsockname");
			return 0;
		}
	}
	sData = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
	if (sData == -1)
	{
		perror("socket");
		return -1;
	}
	if (setsockopt(sData,SOL_SOCKET,SO_REUSEADDR,
				SETSOCKOPT_OPTVAL_TYPE &on,sizeof(on)) == -1)
	{
		perror("setsockopt");
		net_close(sData);
		return -1;
	}
	if (setsockopt(sData,SOL_SOCKET,SO_LINGER,
				SETSOCKOPT_OPTVAL_TYPE &lng,sizeof(lng)) == -1)
	{
		perror("setsockopt");
		net_close(sData);
		return -1;
	}
	if (nControl->cmode == FTPLIB_PASSIVE)
	{
		if (connect(sData, &sin.sa, sizeof(sin.sa)) == -1)
		{
			perror("connect");
			net_close(sData);
			return -1;
		}
	}
	else
	{
		sin.in.sin_port = 0;
		if (bind(sData, &sin.sa, sizeof(sin)) == -1)
		{
			perror("bind");
			net_close(sData);
			return 0;
		}
		if (listen(sData, 1) < 0)
		{
			perror("listen");
			net_close(sData);
			return 0;
		}
		if (getsockname(sData, &sin.sa, &l) < 0)
			return 0;
		sprintf(buf, "PORT %d,%d,%d,%d,%d,%d",
				(unsigned char) sin.sa.sa_data[2],
				(unsigned char) sin.sa.sa_data[3],
				(unsigned char) sin.sa.sa_data[4],
				(unsigned char) sin.sa.sa_data[5],
				(unsigned char) sin.sa.sa_data[0],
				(unsigned char) sin.sa.sa_data[1]);
		if (!FtpSendCmd(buf,'2',nControl))
		{
			net_close(sData);
			return 0;
		}
	}
	ctrl = calloc(1,sizeof(netbuf));
	if (ctrl == NULL)
	{
		perror("calloc");
		net_close(sData);
		return -1;
	}
	if ((mode == 'A') && ((ctrl->buf = malloc(FTPLIB_BUFSIZ)) == NULL))
	{
		perror("calloc");
		net_close(sData);
		free(ctrl);
		return -1;
	}
	ctrl->handle = sData;
	ctrl->dir = dir;
	ctrl->idletime = nControl->idletime;
	ctrl->idlearg = nControl->idlearg;
	ctrl->xfered = 0;
	ctrl->xfered1 = 0;
	ctrl->cbbytes = nControl->cbbytes;
	if (ctrl->idletime.tv_sec || ctrl->idletime.tv_usec || ctrl->cbbytes)
		ctrl->idlecb = nControl->idlecb;
	else
		ctrl->idlecb = NULL;
	*nData = ctrl;
	return 1;
}
Exemplo n.º 18
0
/*
 * FtpCDUp - move to parent directory at remote
 *
 * return 1 if successful, 0 otherwise
 */
GLOBALDEF int FtpCDUp(netbuf *nControl)
{
	if (!FtpSendCmd("CDUP",'2',nControl))
		return 0;
	return 1;
}