示例#1
0
文件: fsp.c 项目: masneyb/gftp
static void
fsp_disconnect (gftp_request * request)
{
  fsp_protocol_data * lpd;

  g_return_if_fail (request != NULL);
  g_return_if_fail (request->protonum == GFTP_FSP_NUM);

  lpd = request->protocol_data;
  g_return_if_fail (lpd != NULL);
 
  if(lpd->file)
  {
      fsp_fclose(lpd->file);
      lpd->file=NULL;
  }
  fsp_close_session(lpd->fsp);
  lpd->fsp=NULL;
  request->datafd = -1;
  if(lpd->dir)
  {
      fsp_closedir(lpd->dir);
      lpd->dir=NULL;
  }
}
示例#2
0
文件: fsp.c 项目: masneyb/gftp
static int
fsp_abort_transfer (gftp_request * request)
{
  fsp_protocol_data * lpd;

  g_return_val_if_fail (request != NULL, GFTP_EFATAL);
  g_return_val_if_fail (request->protonum == GFTP_FSP_NUM, GFTP_EFATAL);

  lpd = request->protocol_data;
  g_return_val_if_fail (lpd->fsp != NULL, GFTP_EFATAL);

  if (lpd->dir)
    {
      fsp_closedir (lpd->dir);
      lpd->dir = NULL;
    }
  if (lpd ->file)
  {
      if(lpd->file->writing && lpd->file->pos>0)
      {
	  /* need to cancel upload in progress */
	  lpd->file->writing=0;
          fsp_install(lpd->fsp,"",0);
      }
      /* we can safely ignore file close error on abort */
      fsp_fclose(lpd->file);
      lpd->file=NULL;
  }

  return (0);
}
示例#3
0
文件: fsp.c 项目: masneyb/gftp
static int
fsp_end_transfer (gftp_request * request)
{
  fsp_protocol_data * lpd;

  g_return_val_if_fail (request != NULL, GFTP_EFATAL);
  g_return_val_if_fail (request->protonum == GFTP_FSP_NUM, GFTP_EFATAL);

  lpd = request->protocol_data;
  g_return_val_if_fail (lpd->fsp != NULL, GFTP_EFATAL);

  if (lpd->dir)
    {
      fsp_closedir (lpd->dir);
      lpd->dir = NULL;
    }
  if (lpd ->file)
  {
      if(fsp_fclose(lpd->file))
      {
	  lpd -> file = NULL;
          request->logging_function (gftp_logging_error, request,
                                 _("Error: Error closing file: %s\n"),
                                 g_strerror (errno));
	  return GFTP_EFATAL;
      }
      lpd->file=NULL;
  }

  return (0);
}
示例#4
0
文件: fsp.c 项目: masneyb/gftp
static int
fsp_put_file (gftp_request * request, const char *filename,
                off_t startsize, off_t totalsize)
{
  fsp_protocol_data * lpd;

  g_return_val_if_fail (request != NULL, GFTP_EFATAL);
  g_return_val_if_fail (request->protonum == GFTP_FSP_NUM, GFTP_EFATAL);
  g_return_val_if_fail (filename != NULL, GFTP_EFATAL);

  lpd = request->protocol_data;
  g_return_val_if_fail (lpd != NULL,GFTP_EFATAL);
  g_return_val_if_fail (lpd->fsp != NULL,GFTP_EFATAL);

  if(lpd->file != NULL)
  {
       fsp_fclose(lpd->file);
       lpd->file=NULL;
  }

  if(fsp_canupload(lpd->fsp,filename))
  {
        request->logging_function (gftp_logging_error, request,
                                 _("Error: Cannot upload file %s\n"),
                                 filename );
        return (GFTP_ERETRYABLE);
  }

      
  lpd->file=fsp_fopen(lpd->fsp,filename, "wb");
  if(lpd->file == NULL)
  {
        request->logging_function (gftp_logging_error, request,
                                 _("Error: Cannot write to file %s: %s\n"),
                                 filename, g_strerror (errno));
        return (GFTP_ERETRYABLE);
  }

  if (fsp_fseek (lpd->file, startsize, SEEK_SET) == -1)
    {
      request->logging_function (gftp_logging_error, request,
                                 _("Error: Cannot seek on file %s: %s\n"),
                                 filename, g_strerror (errno));
      gftp_disconnect (request);
      return (GFTP_ERETRYABLE);
    }
  return (0);
}
示例#5
0
文件: fsp.c 项目: masneyb/gftp
static off_t
fsp_get_file (gftp_request * request, const char *filename,
                off_t startsize)
{
  fsp_protocol_data * lpd;
  struct stat sb;

  g_return_val_if_fail (request != NULL,GFTP_EFATAL);
  g_return_val_if_fail (request->protonum == GFTP_FSP_NUM,GFTP_EFATAL);
  g_return_val_if_fail (filename != NULL, GFTP_EFATAL);

  lpd = request->protocol_data;
  g_return_val_if_fail (lpd != NULL,GFTP_EFATAL);
  g_return_val_if_fail (lpd->fsp != NULL,GFTP_EFATAL);

  /* CHECK: close prev. opened file, is this needed? */
  if(lpd->file != NULL)
  {
       fsp_fclose(lpd->file);
       lpd->file=NULL;
  }

  if(fsp_stat(lpd->fsp,filename,&sb))
      return (GFTP_ERETRYABLE);
  if(!S_ISREG(sb.st_mode))
      return (GFTP_ERETRYABLE);
  lpd->file=fsp_fopen(lpd->fsp,filename,"rb");

  if (fsp_fseek (lpd->file, startsize, SEEK_SET) == -1)
    {
      request->logging_function (gftp_logging_error, request,
                                 _("Error: Cannot seek on file %s: %s\n"),
                                 filename, g_strerror (errno));
      gftp_disconnect (request);
      return (GFTP_ERETRYABLE);
    }

  return (sb.st_size);
}
示例#6
0
文件: fsp.c 项目: Efreak/elinks
static void
do_fsp(struct connection *conn)
{
	FSP_SESSION *ses;
	struct stat sb;
	struct uri *uri = conn->uri;
	struct auth_entry *auth;
	unsigned char *host = get_uri_string(uri, URI_HOST);
	unsigned char *data = get_uri_string(uri, URI_DATA);
	unsigned short port = (unsigned short)get_uri_port(uri);
	unsigned char *password = NULL;

	decode_uri(data);
	if (uri->passwordlen) {
		password = get_uri_string(uri, URI_PASSWORD);
	} else {
		auth = find_auth(uri);
		if (auth) password = auth->password;
	}

	/* fsp_open_session may not set errno if getaddrinfo fails
	 * https://sourceforge.net/tracker/index.php?func=detail&aid=2036798&group_id=93841&atid=605738
	 * Try to detect this bug and use an ELinks-specific error
	 * code instead, so that we can display a message anyway.  */
	errno = 0;
	ses = fsp_open_session(host, port, password);
	if (!ses) {
		if (errno)
			fsp_error(connection_state_for_errno(errno));
		else
			fsp_error(connection_state(S_FSP_OPEN_SESSION_UNKN));
	}

	/* fsplib 0.8 ABI depends on _FILE_OFFSET_BITS
	 * https://sourceforge.net/tracker/index.php?func=detail&aid=1674729&group_id=93841&atid=605738
	 * If ELinks and fsplib are using different values of
	 * _FILE_OFFSET_BITS, then they get different definitions of
	 * struct stat, and the st_size stored by fsp_stat is
	 * typically not the same as the st_size read by ELinks.
	 * Fortunately, st_mode seems to have the same offset and size
	 * in both versions of struct stat.
	 *
	 * If all the bytes used by the 32-bit st_size are also used
	 * by the 64-bit st_size, then ELinks may be able to guess
	 * which ones they are, because the current version 2 of FSP
	 * supports only 32-bit file sizes in protocol packets.  Begin
	 * by filling struct stat with 0xAA so that it's easier to
	 * detect which bytes fsp_stat has left unchanged.  (Only
	 * sb.st_size really needs to be filled, but filling the rest
	 * too helps viewing the data with a debugger.)  */
	memset(&sb, 0xAA, sizeof(sb));
	if (fsp_stat(ses, data, &sb)) fsp_error(connection_state_for_errno(errno));

	if (S_ISDIR(sb.st_mode)) {
		fsp_directory(ses, uri);
	} else { /* regular file */
		char buf[READ_SIZE];
		FSP_FILE *file = fsp_fopen(ses, data, "r");
		int r;

		if (!file) {
			fsp_error(connection_state_for_errno(errno));
		}

#if SIZEOF_OFF_T >= 8
		if (sb.st_size < 0 || sb.st_size > 0xFFFFFFFF) {
			/* Probably a _FILE_OFFSET_BITS mismatch as
			 * described above.  Try to detect which half
			 * of st_size is the real size.  This may
			 * depend on the endianness of the processor
			 * and on the padding in struct stat.  */
			if ((sb.st_size & 0xFFFFFFFF00000000ULL) == 0xAAAAAAAA00000000ULL)
				sb.st_size = sb.st_size & 0xFFFFFFFF;
			else if ((sb.st_size & 0xFFFFFFFF) == 0xAAAAAAAA)
				sb.st_size = (sb.st_size >> 32) & 0xFFFFFFFF;
			else	/* Can't figure it out. */
				sb.st_size = 1;
		}
#endif

		/* Send filesize */
		fprintf(stderr, "%" OFF_PRINT_FORMAT "\n",
			(off_print_T) sb.st_size);
		fclose(stderr);

		while ((r = fsp_fread(buf, 1, READ_SIZE, file)) > 0) {
			int off = 0;

			while (r) {
				int w = safe_write(STDOUT_FILENO, buf + off, r);

				if (w == -1) goto out;
				off += w;
				r -= w;
			}
		}
out:
		fsp_fclose(file);
		fsp_close_session(ses);
		exit(0);
	}