Skip to content

Commit c2458e4

Browse files
author
virco
committed
upload file functions
1 parent 9fb0655 commit c2458e4

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed

psynclib.c

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1528,6 +1528,120 @@ void psync_run_new_version(psync_new_version_t *ver){
15281528
exit(0);
15291529
}
15301530

1531+
static int psync_upload_result(binresult *res, psync_fileid_t *fileid){
1532+
uint64_t result;
1533+
result=psync_find_result(res, "result", PARAM_NUM)->num;
1534+
if (likely(!result)){
1535+
const binresult *meta=psync_find_result(res, "metadata", PARAM_ARRAY)->array[0];
1536+
*fileid=psync_find_result(meta, "fileid", PARAM_NUM)->num;
1537+
psync_free(res);
1538+
return 0;
1539+
}
1540+
else{
1541+
debug(D_WARNING, "uploadfile returned error %u: %s", (unsigned)result, psync_find_result(res, "error", PARAM_STR)->str);
1542+
psync_free(res);
1543+
psync_process_api_error(result);
1544+
return result;
1545+
}
1546+
}
1547+
1548+
static int psync_upload_params(binparam *params, size_t paramcnt, const void *data, size_t length, psync_fileid_t *fileid){
1549+
psync_socket *api;
1550+
binresult *res;
1551+
int tries;
1552+
tries=0;
1553+
do {
1554+
api=psync_apipool_get();
1555+
if (unlikely(!api))
1556+
break;
1557+
if (likely(do_send_command(api, "uploadfile", strlen("uploadfile"), params, paramcnt, length, 0))){
1558+
if (psync_socket_writeall(api, data, length)==length){
1559+
res=get_result(api);
1560+
if (likely(res)){
1561+
psync_apipool_release(api);
1562+
return psync_upload_result(res, fileid);
1563+
}
1564+
}
1565+
}
1566+
psync_apipool_release_bad(api);
1567+
} while (++tries<=PSYNC_RETRY_REQUEST);
1568+
psync_timer_notify_exception();
1569+
return -1;
1570+
1571+
}
1572+
1573+
int psync_upload_data(psync_folderid_t folderid, const char *remote_filename, const void *data, size_t length, psync_fileid_t *fileid){
1574+
binparam params[]={P_STR("auth", psync_my_auth), P_NUM("folderid", folderid), P_STR("filename", remote_filename), P_BOOL("nopartial", 1)};
1575+
return psync_upload_params(params, ARRAY_SIZE(params), data, length, fileid);
1576+
}
1577+
1578+
int psync_upload_data_as(const char *remote_path, const void *data, size_t length, psync_fileid_t *fileid){
1579+
binparam params[]={P_STR("auth", psync_my_auth), P_STR("path", remote_path), P_BOOL("nopartial", 1)};
1580+
return psync_upload_params(params, ARRAY_SIZE(params), data, length, fileid);
1581+
}
1582+
1583+
static int psync_load_file(const char *local_path, char **data, size_t *length){
1584+
psync_file_t fd;
1585+
psync_stat_t st1, st2;
1586+
char *buff;
1587+
size_t len, off;
1588+
ssize_t rd;
1589+
int tries;
1590+
for (tries=0; tries<15; tries++){
1591+
fd=psync_file_open(local_path, P_O_RDONLY, 0);
1592+
if (fd==INVALID_HANDLE_VALUE)
1593+
goto err0;
1594+
if (psync_fstat(fd, &st1))
1595+
goto err1;
1596+
len=psync_stat_size(&st1);
1597+
buff=psync_malloc(len);
1598+
if (!buff)
1599+
goto err1;
1600+
off=0;
1601+
while (off<len){
1602+
rd=psync_file_pread(fd, buff+off, len-off, off);
1603+
if (rd<0)
1604+
break;
1605+
off+=rd;
1606+
}
1607+
psync_file_close(fd);
1608+
if (off==len && !psync_stat(local_path, &st2) && psync_stat_size(&st2)==len && psync_stat_mtime_native(&st1)==psync_stat_mtime_native(&st2)){
1609+
*data=buff;
1610+
*length=len;
1611+
return 0;
1612+
}
1613+
psync_free(buff);
1614+
}
1615+
return -1;
1616+
err1:
1617+
psync_file_close(fd);
1618+
err0:
1619+
return -1;
1620+
}
1621+
1622+
int psync_upload_file(psync_folderid_t folderid, const char *remote_filename, const char *local_path, psync_fileid_t *fileid){
1623+
char *data;
1624+
size_t length;
1625+
int ret;
1626+
if (psync_load_file(local_path, &data, &length))
1627+
return -2;
1628+
ret=psync_upload_data(folderid, remote_filename, data, length, fileid);
1629+
psync_free(data);
1630+
return ret;
1631+
}
1632+
1633+
int psync_upload_file_as(const char *remote_path, const char *local_path, psync_fileid_t *fileid){
1634+
char *data;
1635+
size_t length;
1636+
int ret;
1637+
if (psync_load_file(local_path, &data, &length))
1638+
return -2;
1639+
ret=psync_upload_data_as(remote_path, data, length, fileid);
1640+
psync_free(data);
1641+
return ret;
1642+
}
1643+
1644+
15311645
int psync_password_quality(const char *password){
15321646
uint64_t score=psync_password_score(password);
15331647
if (score<(uint64_t)1<<30)

psynclib.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,25 @@ psync_new_version_t *psync_check_new_version_download_str(const char *os, const
919919
psync_new_version_t *psync_check_new_version_download(const char *os, unsigned long currentversion);
920920
void psync_run_new_version(psync_new_version_t *ver);
921921

922+
/* The following functions provide simplified interface to file upload. While no actual limit is enforced, they are targeted for
923+
* immediate upload of relatively small files (up to few tens of megabytes). These functions:
924+
* - do not obey upload speed limits
925+
* - do not obey stopped/paused state
926+
* - do not increase/touch the number of "files to upload", therefore the status may be "in sync" while these functions actually upload data
927+
* - just try to instantly upload the file regardless of number of files queued up by either/both sync or drive
928+
* - do not support resume of failed uploads
929+
* - overwrite already existing target files
930+
* - functions that work with local files allocate memory equal to the file size (to deal with race conditions of changing files)
931+
*
932+
* All functions return 0 upon success, -1 upon network error, -2 if the local file can not be read or a positive API error code (see
933+
* https://docs.pcloud.com/methods/file/uploadfile.html).
934+
*/
935+
936+
int psync_upload_data(psync_folderid_t folderid, const char *remote_filename, const void *data, size_t length, psync_fileid_t *fileid);
937+
int psync_upload_data_as(const char *remote_path, const void *data, size_t length, psync_fileid_t *fileid);
938+
int psync_upload_file(psync_folderid_t folderid, const char *remote_filename, const char *local_path, psync_fileid_t *fileid);
939+
int psync_upload_file_as(const char *remote_path, const char *local_path, psync_fileid_t *fileid);
940+
922941
/* Filesystem functions.
923942
*
924943
* psync_fs_start() - starts the filesystem

0 commit comments

Comments
 (0)