@@ -1528,6 +1528,120 @@ void psync_run_new_version(psync_new_version_t *ver){
1528
1528
exit (0 );
1529
1529
}
1530
1530
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
+
1531
1645
int psync_password_quality (const char * password ){
1532
1646
uint64_t score = psync_password_score (password );
1533
1647
if (score < (uint64_t )1 <<30 )
0 commit comments