** This function does the work for the writefile() UDF. Refer to ** header comments at the top of this file for details. */
| 2457 | ** header comments at the top of this file for details. |
| 2458 | */ |
| 2459 | static int writeFile( |
| 2460 | sqlite3_context *pCtx, /* Context to return bytes written in */ |
| 2461 | const char *zFile, /* File to write */ |
| 2462 | sqlite3_value *pData, /* Data to write */ |
| 2463 | mode_t mode, /* MODE parameter passed to writefile() */ |
| 2464 | sqlite3_int64 mtime /* MTIME parameter (or -1 to not set time) */ |
| 2465 | ){ |
| 2466 | #if !defined(_WIN32) && !defined(WIN32) |
| 2467 | if( S_ISLNK(mode) ){ |
| 2468 | const char *zTo = (const char*)sqlite3_value_text(pData); |
| 2469 | if( symlink(zTo, zFile)<0 ) return 1; |
| 2470 | }else |
| 2471 | #endif |
| 2472 | { |
| 2473 | if( S_ISDIR(mode) ){ |
| 2474 | if( mkdir(zFile, mode) ){ |
| 2475 | /* The mkdir() call to create the directory failed. This might not |
| 2476 | ** be an error though - if there is already a directory at the same |
| 2477 | ** path and either the permissions already match or can be changed |
| 2478 | ** to do so using chmod(), it is not an error. */ |
| 2479 | struct stat sStat; |
| 2480 | if( errno!=EEXIST |
| 2481 | || 0!=fileStat(zFile, &sStat) |
| 2482 | || !S_ISDIR(sStat.st_mode) |
| 2483 | || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777)) |
| 2484 | ){ |
| 2485 | return 1; |
| 2486 | } |
| 2487 | } |
| 2488 | }else{ |
| 2489 | sqlite3_int64 nWrite = 0; |
| 2490 | const char *z; |
| 2491 | int rc = 0; |
| 2492 | FILE *out = fopen(zFile, "wb"); |
| 2493 | if( out==0 ) return 1; |
| 2494 | z = (const char*)sqlite3_value_blob(pData); |
| 2495 | if( z ){ |
| 2496 | sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out); |
| 2497 | nWrite = sqlite3_value_bytes(pData); |
| 2498 | if( nWrite!=n ){ |
| 2499 | rc = 1; |
| 2500 | } |
| 2501 | } |
| 2502 | fclose(out); |
| 2503 | if( rc==0 && mode && chmod(zFile, mode & 0777) ){ |
| 2504 | rc = 1; |
| 2505 | } |
| 2506 | if( rc ) return 2; |
| 2507 | sqlite3_result_int64(pCtx, nWrite); |
| 2508 | } |
| 2509 | } |
| 2510 | |
| 2511 | if( mtime>=0 ){ |
| 2512 | #if defined(_WIN32) |
| 2513 | #if !SQLITE_OS_WINRT |
| 2514 | /* Windows */ |
| 2515 | FILETIME lastAccess; |
| 2516 | FILETIME lastWrite; |
no test coverage detected