Esempio n. 1
0
static int copy_or_move(ne_session *sess, int is_move, int overwrite,
			int depth, const char *src, const char *dest) 
{
    ne_request *req = ne_request_create( sess, is_move?"MOVE":"COPY", src );

    /* 2518 S8.9.2 says only use Depth: infinity with MOVE. */
    if (!is_move) {
	ne_add_depth_header(req, depth);
    }

#ifdef NE_HAVE_DAV
    if (is_move) {
	ne_lock_using_resource(req, src, NE_DEPTH_INFINITE);
    }
    ne_lock_using_resource(req, dest, NE_DEPTH_INFINITE);
    /* And we need to be able to add members to the destination's parent */
    ne_lock_using_parent(req, dest);
#endif

    ne_print_request_header(req, "Destination", "%s://%s%s", 
			      ne_get_scheme(sess), 
			      ne_get_server_hostport(sess), dest);
    
    ne_add_request_header(req, "Overwrite", overwrite?"T":"F");

    return ne_simple_request(sess, req);
}
Esempio n. 2
0
static int expect100(void)
{
    ne_socket *sock = ne_sock_create();
    char req[BUFSIZ], buf[BUFSIZ];
    ne_status status = {0};
    const ne_inet_addr *ia;
    int success = 0;

    if (strcmp(ne_get_scheme(i_session), "https") == 0) {
        t_context("skipping for SSL server");
        return SKIP;
    }        

    for (ia = ne_addr_first(i_address); ia && !success; 
	 ia = ne_addr_next(i_address))
	success = ne_sock_connect(sock, ia, i_port) == 0;

    ONN("could not connect to server", !success);
    
    sprintf(req, 
	    "PUT %sexpect100 HTTP/1.1" EOL
	    "Host: %s" EOL
	    "Content-Length: 100" EOL
	    "Expect: 100-continue" EOL EOL,
	    i_path, ne_get_server_hostport(i_session));

    NE_DEBUG(NE_DBG_SOCKET, "Request:\n%s", req);

    ONS("sending request", ne_sock_fullwrite(sock, req, strlen(req)));

    switch (ne_sock_block(sock, 30)) {
    case NE_SOCK_TIMEOUT: 
	ONN("timeout waiting for interim response", FAIL);
	break;
    case 0:
	/* no error. */
	break;
    default:
	ONN("error reading from socket", FAIL);
	break;
    }

    ONS("reading status line", ne_sock_readline(sock, buf, BUFSIZ));

    NE_DEBUG(NE_DBG_HTTP, "[status] %s", buf);

    ONN("parse status line", ne_parse_statusline(buf, &status));

    if (status.code == 100) {
	char rbuf[100] = {0};
	
	ONN("write request body", ne_sock_fullwrite(sock, rbuf, 100));
    }

    ne_sock_close(sock);

    return OK;
}
Esempio n. 3
0
svn_error_t *
svn_ra_neon__copy(svn_ra_neon__session_t *ras,
                  svn_boolean_t overwrite,
                  int depth,
                  const char *src,
                  const char *dst,
                  apr_pool_t *pool)
{
  const char *abs_dst;
  apr_hash_t *extra_headers = apr_hash_make(pool);

  abs_dst = apr_psprintf(pool, "%s://%s%s", ne_get_scheme(ras->ne_sess),
                         ne_get_server_hostport(ras->ne_sess), dst);
  apr_hash_set(extra_headers, "Destination", APR_HASH_KEY_STRING, abs_dst);
  apr_hash_set(extra_headers, "Overwrite", APR_HASH_KEY_STRING,
               overwrite ? "T" : "F");
  svn_ra_neon__add_depth_header(extra_headers, depth);

  return svn_ra_neon__simple_request(NULL, ras, "COPY", src, extra_headers,
                                     NULL, 201, 204, pool);
}
Esempio n. 4
0
static csync_vio_method_handle_t *owncloud_open(const char *durl,
                                                int flags,
                                                mode_t mode) {
    char *dir = NULL;
    char getUrl[PATH_MAX];
    int put = 0;
    int rc = NE_OK;
#ifdef _WIN32
    int gtp = 0;
    char tmpname[13];
    mbchar_t winTmp[PATH_MAX];
    mbchar_t *winUrlMB = NULL;
    char *winTmpUtf8 = NULL;
    csync_stat_t sb;
#endif

    struct transfer_context *writeCtx = NULL;
    csync_stat_t statBuf;
    memset( getUrl, '\0', PATH_MAX );

    (void) mode; /* unused on webdav server */
    DEBUG_WEBDAV( "=> open called for %s", durl );

    if( rc == NE_OK )
        dav_connect( durl );

    if (flags & O_WRONLY) {
        put = 1;
    }
    if (flags & O_RDWR) {
        put = 1;
    }
    if (flags & O_CREAT) {
        put = 1;
    }

    if( rc == NE_OK && put ) {
      /* check if the dir name exists. Otherwise return ENOENT */
      dir = c_dirname( durl );
      if (dir == NULL) {
        errno = ENOMEM;
        return NULL;
      }
      DEBUG_WEBDAV("Stating directory %s", dir );
      if( c_streq( dir, _lastDir )) {
        DEBUG_WEBDAV("Dir %s is there, we know it already.", dir);
      } else {
        if( owncloud_stat( dir, (csync_vio_method_handle_t*)(&statBuf) ) == 0 ) {
          DEBUG_WEBDAV("Directory of file to open exists.");
          SAFE_FREE( _lastDir );
          _lastDir = c_strdup(dir);

        } else {
          DEBUG_WEBDAV("Directory %s of file to open does NOT exist.", dir );
          /* the directory does not exist. That is an ENOENT */
          errno = ENOENT;
          SAFE_FREE( dir );
          return NULL;
        }
      }
    }

    writeCtx = c_malloc( sizeof(struct transfer_context) );

    writeCtx->url = _cleanPath( durl );
    if( ! writeCtx->url ) {
        DEBUG_WEBDAV("Failed to clean path for %s", durl );
        errno = EACCES;
        rc = NE_ERROR;
    }

    if( rc == NE_OK && put) {
        DEBUG_WEBDAV("PUT request on %s!", writeCtx->url);
        writeCtx->req = ne_request_create(dav_session.ctx, "PUT", writeCtx->url);
        writeCtx->method = "PUT";
    }

    if( rc == NE_OK && ! put ) {
        writeCtx->req = 0;
        writeCtx->method = "GET";

        /* the download via the get function requires a full uri */
        snprintf( getUrl, PATH_MAX, "%s://%s%s", ne_get_scheme( dav_session.ctx),
                  ne_get_server_hostport( dav_session.ctx ), writeCtx->url );
        DEBUG_WEBDAV("GET request on %s", getUrl );

        writeCtx->req = ne_request_create( dav_session.ctx, "GET", getUrl );

        /* Call the progress callback */
        if (_file_progress_cb) {
            ne_set_notifier(dav_session.ctx, ne_notify_status_cb, writeCtx);
            _file_progress_cb( writeCtx->url, CSYNC_NOTIFY_START_DOWNLOAD, 0 , 0, _userdata);
        }
    }

    if( rc != NE_OK ) {
        SAFE_FREE( writeCtx );
        writeCtx = NULL;
    }

    SAFE_FREE( dir );

    return (csync_vio_method_handle_t *) writeCtx;
}
Esempio n. 5
0
static svn_error_t *
generate_error(svn_ra_neon__request_t *req, apr_pool_t *pool)
{
  int errcode = SVN_ERR_RA_DAV_REQUEST_FAILED;
  const char *context =
    apr_psprintf(req->pool, _("%s of '%s'"), req->method, req->url);
  const char *msg;
  const char *hostport;

  /* Convert the return codes. */
  switch (req->rv)
    {
    case NE_OK:
      switch (req->code)
        {
        case 404:
          return svn_error_create(SVN_ERR_FS_NOT_FOUND, NULL,
                                  apr_psprintf(pool, _("'%s' path not found"),
                                               req->url));
        case 403:
          return svn_error_create(SVN_ERR_RA_DAV_FORBIDDEN, NULL,
                                  apr_psprintf(pool, _("Access to '%s' forbidden"),
                                               req->url));

        case 301:
        case 302:
        case 307:
          return svn_error_create
            (SVN_ERR_RA_DAV_RELOCATED, NULL,
             apr_psprintf(pool,
                          (req->code == 301)
                          ? _("Repository moved permanently to '%s';"
                              " please relocate")
                          : _("Repository moved temporarily to '%s';"
                              " please relocate"),
                          svn_ra_neon__request_get_location(req, pool)));

        default:
          return svn_error_create
            (errcode, NULL,
             apr_psprintf(pool,
                          _("Server sent unexpected return value (%d %s) "
                            "in response to %s request for '%s'"), req->code,
                          req->code_desc, req->method, req->url));
        }
    case NE_AUTH:
    case NE_PROXYAUTH:
      errcode = SVN_ERR_RA_NOT_AUTHORIZED;
#ifdef SVN_NEON_0_27
      /* neon >= 0.27 gives a descriptive error message after auth
       * failure; expose this since it's a useful diagnostic e.g. for
       * an unsupported challenge scheme, or a local GSSAPI error due
       * to an expired ticket. */
      SVN_ERR(svn_utf_cstring_to_utf8(&msg, ne_get_error(req->ne_sess), pool));
      msg = apr_psprintf(pool, _("authorization failed: %s"), msg);
#else
      msg = _("authorization failed");
#endif
      break;

    case NE_CONNECT:
      msg = _("could not connect to server");
      break;

    case NE_TIMEOUT:
      msg = _("timed out waiting for server");
      break;

    default:
      /* Get the error string from neon and convert to UTF-8. */
      SVN_ERR(svn_utf_cstring_to_utf8(&msg, ne_get_error(req->ne_sess), pool));
      break;
    }

  /* The hostname may contain non-ASCII characters, so convert it to UTF-8. */
  SVN_ERR(svn_utf_cstring_to_utf8(&hostport,
                                  ne_get_server_hostport(req->ne_sess), pool));

  /*### This is a translation nightmare. Make sure to compose full strings
    and mark those for translation. */
  return svn_error_createf(errcode, NULL, _("%s: %s (%s://%s)"),
                           context, msg, ne_get_scheme(req->ne_sess),
                           hostport);
}
Esempio n. 6
0
static csync_vio_method_handle_t *owncloud_open(const char *durl,
                                                int flags,
                                                mode_t mode) {
    char *uri = NULL;
    char *dir = NULL;
    char getUrl[PATH_MAX];
    int put = 0;
    int rc = NE_OK;
#ifdef _WIN32
    int gtp = 0;
    char tmpname[13];
#endif

    struct transfer_context *writeCtx = NULL;
    csync_stat_t statBuf;
    memset( getUrl, '\0', PATH_MAX );

    (void) mode; /* unused on webdav server */
    DEBUG_WEBDAV(( "=> open called for %s\n", durl ));

    uri = _cleanPath( durl );
    if( ! uri ) {
        DEBUG_WEBDAV(("Failed to clean path for %s\n", durl ));
        errno = EACCES;
        rc = NE_ERROR;
    }

    if( rc == NE_OK )
        dav_connect( durl );

    if (flags & O_WRONLY) {
        put = 1;
    }
    if (flags & O_RDWR) {
        put = 1;
    }
    if (flags & O_CREAT) {
        put = 1;
    }


    if( rc == NE_OK && put ) {
        /* check if the dir name exists. Otherwise return ENOENT */
        dir = c_dirname( durl );
	if (dir == NULL) {
            errno = ENOMEM;
	    return NULL;
	}
        DEBUG_WEBDAV(("Stating directory %s\n", dir ));
        if( c_streq( dir, _lastDir )) {
            DEBUG_WEBDAV(("Dir %s is there, we know it already.\n", dir));
        } else {
            if( owncloud_stat( dir, (csync_vio_method_handle_t*)(&statBuf) ) == 0 ) {
                DEBUG_WEBDAV(("Directory of file to open exists.\n"));
                SAFE_FREE( _lastDir );
                _lastDir = c_strdup(dir);

            } else {
                DEBUG_WEBDAV(("Directory %s of file to open does NOT exist.\n", dir ));
                /* the directory does not exist. That is an ENOENT */
                errno = ENOENT;
                SAFE_FREE( dir );
                return NULL;
            }
        }
    }

    writeCtx = c_malloc( sizeof(struct transfer_context) );
    writeCtx->bytes_written = 0;
    if( rc == NE_OK ) {
        /* open a temp file to store the incoming data */
#ifdef _WIN32
        memset( tmpname, '\0', 13 );
        gtp = GetTempPath( PATH_MAX, getUrl );
        DEBUG_WEBDAV(("win32 tmp path: %s\n", getUrl ));
        if ( gtp > MAX_PATH || (gtp == 0) ) {
            DEBUG_WEBDAV(("Failed to compute Win32 tmp path, trying /tmp\n"));
            strcpy( getUrl, "/tmp/");
        }
        strcpy( tmpname, "csync.XXXXXX" );
        if( c_tmpname( tmpname ) == 0 ) {
            _fmode = _O_BINARY;
            strcat( getUrl, tmpname );
            writeCtx->tmpFileName = c_strdup( getUrl );
            writeCtx->fd = open( writeCtx->tmpFileName, O_RDWR | O_CREAT | O_EXCL, 0600 );
	} else {
	   writeCtx->fd = -1;
	}
#else
        writeCtx->tmpFileName = c_strdup( "/tmp/csync.XXXXXX" );
        writeCtx->fd = mkstemp( writeCtx->tmpFileName );
#endif
        DEBUG_WEBDAV(("opening temp directory %s: %d\n", writeCtx->tmpFileName, writeCtx->fd ));
        if( writeCtx->fd == -1 ) {
	    DEBUG_WEBDAV(("Failed to open temp file, errno = %d\n", errno ));
            rc = NE_ERROR;
            /* errno is set by the mkstemp call above. */
        }
    }

    if( rc == NE_OK && put) {
        DEBUG_WEBDAV(("PUT request on %s!\n", uri));
        /* reset the write buffer */
        writeCtx->bytes_written = 0;
        writeCtx->fileWritten = 0;   /* flag to indicate if contents was pushed to file */

        writeCtx->req = ne_request_create(dav_session.ctx, "PUT", uri);
	writeCtx->method = "PUT";
    }


    if( rc == NE_OK && ! put ) {
        writeCtx->req = 0;
        writeCtx->method = "GET";

        /* Download the data into a local temp file. */
        /* the download via the get function requires a full uri */
        snprintf( getUrl, PATH_MAX, "%s://%s%s", ne_get_scheme( dav_session.ctx),
                  ne_get_server_hostport( dav_session.ctx ), uri );
        DEBUG_WEBDAV(("GET request on %s\n", getUrl ));

#define WITH_HTTP_COMPRESSION
#ifdef WITH_HTTP_COMPRESSION
        writeCtx->req = ne_request_create( dav_session.ctx, "GET", getUrl );

        /* Allow compressed content by setting the header */
        ne_add_request_header( writeCtx->req, "Accept-Encoding", "gzip,deflate" );

        /* hook called before the content is parsed to set the correct reader,
         * either the compressed- or uncompressed reader.
         */
        ne_hook_post_headers( dav_session.ctx, install_content_reader, writeCtx );

        /* actually do the request */
        rc = ne_request_dispatch(writeCtx->req );
        /* possible return codes are:
         *  NE_OK, NE_AUTH, NE_CONNECT, NE_TIMEOUT, NE_ERROR (from ne_request.h)
         */

        if( rc != NE_OK || (rc == NE_OK && ne_get_status(writeCtx->req)->klass != 2) ) {
            DEBUG_WEBDAV(("request_dispatch failed with rc=%d\n", rc ));
            if( rc == NE_OK ) rc = NE_ERROR;
            errno = EACCES;
        }

        /* delete the hook again, otherwise they get chained as they are with the session */
        ne_unhook_post_headers( dav_session.ctx, install_content_reader, writeCtx );

        /* if the compression handle is set through the post_header hook, delete it. */
        if( writeCtx->decompress ) {
            ne_decompress_destroy( writeCtx->decompress );
        }

        /* delete the request in any case */
        ne_request_destroy(writeCtx->req);
#else
        DEBUG_WEBDAV(("GET Compression not supported!\n"));
        rc = ne_get( dav_session.ctx, getUrl, writeCtx->fd );  /* FIX_ESCAPE? */
#endif
        if( rc != NE_OK ) {
            DEBUG_WEBDAV(("Download to local file failed: %d.\n", rc));
            errno = EACCES;
        }
        if( close( writeCtx->fd ) == -1 ) {
            DEBUG_WEBDAV(("Close of local download file failed.\n"));
            writeCtx->fd = -1;
            rc = NE_ERROR;
            errno = EACCES;
        }

        writeCtx->fd = -1;
    }

    if( rc != NE_OK ) {
        SAFE_FREE( writeCtx );
    }

    SAFE_FREE( uri );
    SAFE_FREE( dir );

    return (csync_vio_method_handle_t *) writeCtx;
}