void sg_client__c__push_begin(SG_context* pCtx, SG_client * pClient, SG_pathname** ppFragballDirPathname, SG_client_push_handle** ppPush) { sg_client_c_push_handle* pPush = NULL; sg_client_c_instance_data* pMe = NULL; SG_NULLARGCHECK_RETURN(pClient); SG_NULLARGCHECK_RETURN(ppFragballDirPathname); SG_NULLARGCHECK_RETURN(ppPush); pMe = (sg_client_c_instance_data*)pClient->p_vtable_instance_data; // Alloc a push handle. SG_ERR_CHECK( SG_alloc(pCtx, 1, sizeof(sg_client_c_push_handle), &pPush) ); // Tell the server we're about to push. We get back a push ID, which we save in the push handle. SG_ERR_CHECK( SG_server__push_begin(pCtx, pMe->pServer, pClient->psz_remote_repo_spec, (const char **)&pPush->pszPushId) ); /* This is a local push, so we tell our caller to put fragballs directly in the server's staging area. */ SG_ERR_CHECK( SG_server__push_get_staging_path(pCtx, pMe->pServer, pPush->pszPushId, ppFragballDirPathname) ); // Return the new push handle. *ppPush = (SG_client_push_handle*)pPush; pPush = NULL; /* fall through */ fail: _NULLFREE_PUSH_HANDLE(pCtx, pPush); }
void sg_sync_client__http__push_end( SG_context * pCtx, SG_sync_client * pSyncClient, SG_sync_client_push_handle** ppPush) { sg_sync_client_http_push_handle* pMyPush = NULL; char* pszUrl = NULL; SG_string* pstr = NULL; SG_NULLARGCHECK_RETURN(pSyncClient); SG_NULL_PP_CHECK_RETURN(ppPush); pMyPush = (sg_sync_client_http_push_handle*)*ppPush; // Get the remote URL SG_ERR_CHECK( _get_sync_url(pCtx, pSyncClient->psz_remote_repo_spec, SYNC_URL_SUFFIX, pMyPush->pszPushId, NULL, &pszUrl) ); SG_ERR_CHECK( do_url( pCtx, pszUrl, "DELETE", NULL, pSyncClient->psz_username, pSyncClient->psz_password, &pstr, NULL, SG_TRUE ) ); // fall through fail: // We free the push handle even on failure, because SG_push_handle is opaque outside this file: // this is the only way to free it. _NULLFREE_PUSH_HANDLE(pCtx, pMyPush); *ppPush = NULL; SG_NULLFREE(pCtx, pszUrl); SG_STRING_NULLFREE(pCtx, pstr); }
void sg_client__c__push_end(SG_context * pCtx, SG_client * pClient, SG_client_push_handle** ppPush) { sg_client_c_instance_data* pMe = NULL; sg_client_c_push_handle* pMyPush = NULL; SG_NULLARGCHECK_RETURN(pClient); SG_NULLARGCHECK_RETURN(ppPush); pMe = (sg_client_c_instance_data*)pClient->p_vtable_instance_data; pMyPush = (sg_client_c_push_handle*)*ppPush; SG_ERR_CHECK( SG_server__push_end(pCtx, pMe->pServer, pMyPush->pszPushId) ); // fall through fail: // We free the push handle even on failure, because SG_push_handle is opaque outside this file: // this is the only way to free it. _NULLFREE_PUSH_HANDLE(pCtx, pMyPush); *ppPush = NULL; }
void sg_sync_client__http__push_begin( SG_context* pCtx, SG_sync_client * pSyncClient, SG_pathname** pFragballDirPathname, SG_sync_client_push_handle** ppPush) { char* pszUrl = NULL; sg_sync_client_http_push_handle* pPush = NULL; SG_vhash* pvhResponse = NULL; SG_pathname* pPathUserTemp = NULL; SG_pathname* pPathFragballDir = NULL; char bufTid[SG_TID_MAX_BUFFER_LENGTH]; SG_string* pstr = NULL; SG_NULLARGCHECK_RETURN(pSyncClient); SG_NULLARGCHECK_RETURN(pFragballDirPathname); SG_NULLARGCHECK_RETURN(ppPush); // Get the URL we're going to post to SG_ERR_CHECK( _get_sync_url(pCtx, pSyncClient->psz_remote_repo_spec, SYNC_URL_SUFFIX JSON_URL_SUFFIX, NULL, NULL, &pszUrl) ); SG_ERR_CHECK( do_url(pCtx, pszUrl, "POST", NULL, pSyncClient->psz_username, pSyncClient->psz_password, &pstr, NULL, SG_TRUE) ); SG_ERR_CHECK( SG_vhash__alloc__from_json__sz(pCtx, &pvhResponse, SG_string__sz(pstr)) ); SG_STRING_NULLFREE(pCtx, pstr); // Alloc a push handle. Stuff the push ID we received into it. { const char* pszRef = NULL; SG_ERR_CHECK( SG_alloc(pCtx, 1, sizeof(sg_sync_client_http_push_handle), &pPush) ); SG_ERR_CHECK( SG_vhash__get__sz(pCtx, pvhResponse, PUSH_ID_KEY, &pszRef) ); SG_ERR_CHECK( SG_strdup(pCtx, pszRef, &pPush->pszPushId) ); } // Create a temporary local directory for stashing fragballs before shipping them over the network. SG_ERR_CHECK( SG_PATHNAME__ALLOC__USER_TEMP_DIRECTORY(pCtx, &pPathUserTemp) ); SG_ERR_CHECK( SG_tid__generate(pCtx, bufTid, SG_TID_MAX_BUFFER_LENGTH) ); SG_ERR_CHECK( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPathFragballDir, pPathUserTemp, bufTid) ); SG_ERR_CHECK( SG_fsobj__mkdir__pathname(pCtx, pPathFragballDir) ); // Tell caller where to stash fragballs for this push. SG_RETURN_AND_NULL(pPathFragballDir, pFragballDirPathname); // Return the new push handle. *ppPush = (SG_sync_client_push_handle*)pPush; pPush = NULL; /* fall through */ fail: SG_STRING_NULLFREE(pCtx, pstr); if(SG_context__err_equals(pCtx, SG_ERR_SERVER_HTTP_ERROR)) { const char * szInfo = NULL; if(SG_IS_OK(SG_context__err_get_description(pCtx, &szInfo)) && strcmp(szInfo, "405")==0) SG_ERR_RESET_THROW(SG_ERR_SERVER_DOESNT_ACCEPT_PUSHES); } _NULLFREE_PUSH_HANDLE(pCtx, pPush); SG_NULLFREE(pCtx, pszUrl); SG_PATHNAME_NULLFREE(pCtx, pPathUserTemp); SG_PATHNAME_NULLFREE(pCtx, pPathFragballDir); SG_VHASH_NULLFREE(pCtx, pvhResponse); }