Example #1
0
File: fsp.c Project: masneyb/gftp
static off_t 
fsp_get_file_size (gftp_request * request, const char *filename)
{
  struct stat st;
  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->fsp != NULL, GFTP_EFATAL);

  if (fsp_stat (lpd->fsp,filename, &st) != 0)
    return (GFTP_ERETRYABLE);

  return (st.st_size);
}
Example #2
0
File: fsp.c Project: 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);
}
Example #3
0
File: fsp.c Project: masneyb/gftp
static int
fsp_stat_filename (gftp_request * request, const char *filename,
                   mode_t * mode, off_t * filesize)
{
  fsp_protocol_data * lpd;
  struct stat st;

  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->fsp != NULL, GFTP_EFATAL);

  if (fsp_stat (lpd->fsp,filename, &st) != 0)
    return (GFTP_ERETRYABLE);

  *mode = st.st_mode;
  *filesize = st.st_size;

  return (0);
}
Example #4
0
static bool get_sorted_dir_mtime(vfs_handle_struct *handle,
				struct dirsort_privates *data,
				struct timespec *ret_mtime)
{
	int ret;
	struct timespec mtime;

	if (data->fsp) {
		ret = fsp_stat(data->fsp);
		mtime = data->fsp->fsp_name->st.st_ex_mtime;
	} else {
		ret = SMB_VFS_STAT(handle->conn, data->smb_fname);
		mtime = data->smb_fname->st.st_ex_mtime;
	}

	if (ret == -1) {
		return false;
	}

	*ret_mtime = mtime;

	return true;
}
Example #5
0
File: fsp.c Project: 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);
	}