Overview
Comment: | Work towards gutting AppFSd to rewrite |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | tcl-ops |
Files: | files | file ages | folders |
SHA1: | aca3a93d56aeab2902fed4f583aa4bd86e57818b |
User & Date: | rkeene on 2014-11-06 17:11:01 |
Other Links: | manifest | tags |
Context
2014-11-06
| ||
18:29 | Minor update check-in: 5bd7399e05 user: rkeene tags: tcl-ops | |
17:11 | Work towards gutting AppFSd to rewrite check-in: aca3a93d56 user: rkeene tags: tcl-ops | |
16:20 | Merged in internal_sha1 branch since we should use that as the basis going forward check-in: 5ffd966f05 user: rkeene tags: tcl-ops | |
Changes
Modified appfsd.c from [a8794a7145] to [8dc47d059d].
1 1 #define FUSE_USE_VERSION 26 2 2 3 3 #include <sys/types.h> 4 -#include <sqlite3.h> 5 4 #include <pthread.h> 6 5 #include <string.h> 7 6 #include <stdarg.h> 8 7 #include <stdlib.h> 9 8 #include <unistd.h> 10 9 #include <errno.h> 11 10 #include <fcntl.h> ................................................................................ 26 25 #else 27 26 #define APPFS_DEBUG(x...) /**/ 28 27 #endif 29 28 30 29 static pthread_key_t interpKey; 31 30 32 31 struct appfs_thread_data { 33 - sqlite3 *db; 34 32 const char *cachedir; 35 33 time_t boottime; 36 - const char *platform; 37 34 struct { 38 35 int writable; 39 36 } options; 40 37 }; 41 38 42 39 struct appfs_thread_data globalThread; 43 40 ................................................................................ 73 70 struct { 74 71 off_t size; 75 72 char source[256]; 76 73 } symlink; 77 74 } typeinfo; 78 75 }; 79 76 80 -struct appfs_sqlite3_query_cb_handle { 81 - struct appfs_children *head; 82 - int argc; 83 - const char *fmt; 84 -}; 85 - 86 77 static Tcl_Interp *appfs_create_TclInterp(const char *cachedir) { 87 78 Tcl_Interp *interp; 88 79 int tcl_ret; 89 80 90 81 APPFS_DEBUG("Creating new Tcl interpreter for TID = 0x%llx", (unsigned long long) pthread_self()); 91 82 92 83 interp = Tcl_CreateInterp(); ................................................................................ 107 98 } 108 99 109 100 tcl_ret = Tcl_Eval(interp, "package ifneeded sha1 1.0 [list load {} sha1]"); 110 101 if (tcl_ret != TCL_OK) { 111 102 fprintf(stderr, "Unable to initialize Tcl SHA1. Aborting.\n"); 112 103 fprintf(stderr, "Tcl Error is: %s\n", Tcl_GetStringResult(interp)); 113 104 105 + Tcl_DeleteInterp(interp); 106 + 107 + return(NULL); 108 + } 109 + 110 + tcl_ret = Tcl_Eval(interp, "package ifneeded appfsd 1.0 [list load {} appfsd]"); 111 + if (tcl_ret != TCL_OK) { 112 + fprintf(stderr, "Unable to initialize Tcl AppFS Package. Aborting.\n"); 113 + fprintf(stderr, "Tcl Error is: %s\n", Tcl_GetStringResult(interp)); 114 + 114 115 Tcl_DeleteInterp(interp); 115 116 116 117 return(NULL); 117 118 } 118 119 119 120 tcl_ret = Tcl_Eval(interp, "" 120 121 #include "appfsd.tcl.h" ................................................................................ 269 270 270 271 return; 271 272 } 272 273 273 274 return; 274 275 } 275 276 276 -#define appfs_free_list_type(id, type) static void appfs_free_list_ ## id(type *head) { \ 277 - type *obj, *next; \ 278 - for (obj = head; obj; obj = next) { \ 279 - next = obj->_next; \ 280 - ckfree((void *) obj); \ 281 - } \ 282 -} 283 - 284 -appfs_free_list_type(children, struct appfs_children) 285 - 286 277 static uid_t appfs_get_fsuid(void) { 287 278 struct fuse_context *ctx; 288 279 289 280 ctx = fuse_get_context(); 290 281 if (ctx == NULL) { 291 282 return(1); 292 283 } 293 284 294 285 return(ctx->uid); 295 286 } 296 287 297 -static const char *appfs_get_homedir(uid_t fsuid) { 288 +static char *appfs_get_homedir(uid_t fsuid) { 298 289 struct passwd entry, *result; 299 290 struct stat stbuf; 300 291 char buf[1024], *retval; 301 292 int gpu_ret, stat_ret; 302 293 303 294 gpu_ret = getpwuid_r(fsuid, &entry, buf, sizeof(buf), &result); 304 295 if (gpu_ret != 0) { ................................................................................ 332 323 result->pw_dir, 333 324 (unsigned long long) stbuf.st_uid 334 325 ); 335 326 336 327 return(NULL); 337 328 } 338 329 339 - retval = sqlite3_mprintf("%s", result->pw_dir); 330 + retval = strdup(result->pw_dir); 340 331 341 332 return(retval); 342 333 } 343 334 344 -static int appfs_getpackage_name_cb(void *_package_name, int columns, char **values, char **names) { 345 - char **package_name; 346 - 347 - if (columns != 1) { 348 - return(1); 349 - } 350 - 351 - package_name = _package_name; 352 - 353 - *package_name = sqlite3_mprintf("%s", values[0]); 354 - 355 - return(0); 356 -} 357 - 358 -static char *appfs_getpackage_name(const char *hostname, const char *package_hash) { 359 - char *sql; 360 - int sqlite_ret; 361 - char *package_name = NULL; 362 - 363 - sql = sqlite3_mprintf("SELECT package FROM packages WHERE hostname = %Q AND sha1 = %Q LIMIT 1;", hostname, package_hash); 364 - if (sql == NULL) { 365 - APPFS_DEBUG("Call to sqlite3_mprintf failed."); 366 - 367 - return(sqlite3_mprintf("%s", "unknown-package-name")); 368 - } 369 - sqlite_ret = sqlite3_exec(globalThread.db, sql, appfs_getpackage_name_cb, &package_name, NULL); 370 - sqlite3_free(sql); 371 - 372 - if (sqlite_ret != SQLITE_OK) { 373 - APPFS_DEBUG("Call to sqlite3_exec failed."); 374 - 375 - return(sqlite3_mprintf("%s", "unknown-package-name")); 376 - } 377 - 378 - return(package_name); 379 -} 380 - 381 -static struct appfs_children *appfs_getchildren_fs(struct appfs_children *in_children, const char *fspath) { 382 - APPFS_DEBUG("Searching %s", fspath); 383 - 384 - return(in_children); 385 -} 386 - 387 -static int appfs_getchildren_cb(void *_head, int columns, char **values, char **names) { 388 - struct appfs_children **head_p, *obj; 389 - 390 - head_p = _head; 391 - 392 - obj = (void *) ckalloc(sizeof(*obj)); 393 - 394 - snprintf(obj->name, sizeof(obj->name), "%s", values[0]); 395 - 396 - if (*head_p == NULL) { 397 - obj->counter = 0; 398 - } else { 399 - obj->counter = (*head_p)->counter + 1; 400 - } 401 - 402 - obj->_next = *head_p; 403 - *head_p = obj; 404 - 405 - return(0); 406 - 335 +static int tcl_appfs_get_homedir(ClientData cd, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { 336 + char *homedir; 337 + 338 + if (objc != 1) { 339 + Tcl_WrongNumArgs(interp, 1, objv, NULL); 340 + return(TCL_ERROR); 341 + } 342 + 343 + homedir = appfs_get_homedir(appfs_get_fsuid()); 344 + 345 + if (homedir == NULL) { 346 + return(TCL_ERROR); 347 + } 348 + 349 + Tcl_SetObjResult(interp, Tcl_NewStringObj(homedir, -1)); 350 + 351 + free(homedir); 352 + 353 + return(TCL_OK); 407 354 } 408 355 409 356 static struct appfs_children *appfs_getchildren(const char *hostname, const char *package_hash, const char *path, int *children_count_p) { 410 - struct appfs_children *head = NULL; 411 - char *sql, *filebuf, *homedir = NULL; 412 - int sqlite_ret; 413 - uid_t fsuid; 414 - 415 - if (children_count_p == NULL) { 416 - return(NULL); 417 - } 418 - 419 - appfs_update_index(hostname); 420 - appfs_update_manifest(hostname, package_hash); 421 - 422 - sql = sqlite3_mprintf("SELECT file_name FROM files WHERE package_sha1 = %Q AND file_directory = %Q;", package_hash, path); 423 - if (sql == NULL) { 424 - APPFS_DEBUG("Call to sqlite3_mprintf failed."); 425 - 426 - return(NULL); 427 - } 428 - 429 - APPFS_DEBUG("SQL: %s", sql); 430 - sqlite_ret = sqlite3_exec(globalThread.db, sql, appfs_getchildren_cb, &head, NULL); 431 - sqlite3_free(sql); 432 - 433 - if (sqlite_ret != SQLITE_OK) { 434 - APPFS_DEBUG("Call to sqlite3_exec failed."); 435 - 436 - appfs_free_list_children(head); 437 - 438 - return(NULL); 439 - } 440 - 441 - if (globalThread.options.writable) { 442 - /* Determine user of process accessing this file */ 443 - fsuid = appfs_get_fsuid(); 444 - 445 - /* Check filesystem paths for updated files */ 446 - /** Check the global directory (/etc) **/ 447 - filebuf = sqlite3_mprintf("/etc/appfs/%z@%s/%s", appfs_getpackage_name(hostname, package_hash), hostname, path); 448 - if (filebuf == NULL) { 449 - APPFS_DEBUG("Call to sqlite3_mprintf failed."); 450 - 451 - return(NULL); 452 - } 453 - 454 - head = appfs_getchildren_fs(head, filebuf); 455 - 456 - sqlite3_free(filebuf); 457 - 458 - /** Check the user's directory, if we are not root **/ 459 - if (fsuid != 0) { 460 - homedir = (char *) appfs_get_homedir(fsuid); 461 - } 462 - 463 - if (homedir != NULL) { 464 - filebuf = sqlite3_mprintf("%z/.appfs/%z@%s/%s", homedir, appfs_getpackage_name(hostname, package_hash), hostname, path); 465 - 466 - if (filebuf == NULL) { 467 - APPFS_DEBUG("Call to sqlite3_mprintf failed."); 468 - 469 - return(NULL); 470 - } 471 - 472 - head = appfs_getchildren_fs(head, filebuf); 473 - 474 - sqlite3_free(filebuf); 475 - } 476 - } 477 - 478 - if (head != NULL) { 479 - *children_count_p = head->counter + 1; 480 - } else { 481 - *children_count_p = 0; 482 - } 483 - 484 - return(head); 485 -} 486 - 487 -static int appfs_sqlite3_query_cb(void *_cb_handle, int columns, char **values, char **names) { 488 - struct appfs_sqlite3_query_cb_handle *cb_handle; 489 - struct appfs_children *obj; 490 - 491 - cb_handle = _cb_handle; 492 - 493 - obj = (void *) ckalloc(sizeof(*obj)); 494 - 495 - switch (cb_handle->argc) { 496 - case 1: 497 - snprintf(obj->name, sizeof(obj->name), cb_handle->fmt, values[0]); 498 - break; 499 - case 2: 500 - snprintf(obj->name, sizeof(obj->name), cb_handle->fmt, values[0], values[1]); 501 - break; 502 - case 3: 503 - snprintf(obj->name, sizeof(obj->name), cb_handle->fmt, values[0], values[1], values[2]); 504 - break; 505 - case 4: 506 - snprintf(obj->name, sizeof(obj->name), cb_handle->fmt, values[0], values[1], values[2], values[3]); 507 - break; 508 - } 509 - 510 - if (cb_handle->head == NULL) { 511 - obj->counter = 0; 512 - } else { 513 - obj->counter = cb_handle->head->counter + 1; 514 - } 515 - 516 - obj->_next = cb_handle->head; 517 - cb_handle->head = obj; 518 - 519 - return(0); 520 -} 521 - 522 -static struct appfs_children *appfs_sqlite3_query(char *sql, int argc, const char *fmt, int *results_count_p) { 523 - struct appfs_sqlite3_query_cb_handle cb_handle; 524 - int sqlite_ret; 525 - 526 - if (results_count_p == NULL) { 527 - return(NULL); 528 - } 529 - 530 - if (sql == NULL) { 531 - APPFS_DEBUG("Call to sqlite3_mprintf probably failed."); 532 - 533 - return(NULL); 534 - } 535 - 536 - if (fmt == NULL) { 537 - fmt = "%s"; 538 - } 539 - 540 - cb_handle.head = NULL; 541 - cb_handle.argc = argc; 542 - cb_handle.fmt = fmt; 543 - 544 - APPFS_DEBUG("SQL: %s", sql); 545 - sqlite_ret = sqlite3_exec(globalThread.db, sql, appfs_sqlite3_query_cb, &cb_handle, NULL); 546 - sqlite3_free(sql); 547 - 548 - if (sqlite_ret != SQLITE_OK) { 549 - APPFS_DEBUG("Call to sqlite3_exec failed."); 550 - 551 - return(NULL); 552 - } 553 - 554 - if (cb_handle.head != NULL) { 555 - *results_count_p = cb_handle.head->counter + 1; 556 - } 557 - 558 - return(cb_handle.head); 559 -} 560 - 561 -static int appfs_lookup_package_hash_cb(void *_retval, int columns, char **values, char **names) { 562 - char **retval = _retval; 563 - 564 - *retval = strdup(values[0]); 565 - 566 - return(0); 567 357 } 568 358 569 359 static char *appfs_lookup_package_hash(const char *hostname, const char *package, const char *os, const char *cpuArch, const char *version) { 570 - char *sql; 571 - char *retval = NULL; 572 - int sqlite_ret; 573 - 574 - appfs_update_index(hostname); 575 - 576 - sql = sqlite3_mprintf("SELECT sha1 FROM packages WHERE hostname = %Q AND package = %Q AND os = %Q AND cpuArch = %Q AND version = %Q;", 577 - hostname, 578 - package, 579 - os, 580 - cpuArch, 581 - version 582 - ); 583 - if (sql == NULL) { 584 - APPFS_DEBUG("Call to sqlite3_mprintf failed."); 585 - 586 - return(NULL); 587 - } 588 - 589 - APPFS_DEBUG("SQL: %s", sql); 590 - sqlite_ret = sqlite3_exec(globalThread.db, sql, appfs_lookup_package_hash_cb, &retval, NULL); 591 - sqlite3_free(sql); 592 - 593 - if (sqlite_ret != SQLITE_OK) { 594 - APPFS_DEBUG("Call to sqlite3_exec failed."); 595 - 596 - return(NULL); 597 - } 598 - 599 - return(retval); 600 -} 601 - 602 -static int appfs_getfileinfo_cb(void *_pathinfo, int columns, char **values, char **names) { 603 - struct appfs_pathinfo *pathinfo = _pathinfo; 604 - const char *type, *time, *source, *size, *perms, *sha1, *rowid; 605 - 606 - type = values[0]; 607 - time = values[1]; 608 - source = values[2]; 609 - size = values[3]; 610 - perms = values[4]; 611 - sha1 = values[5]; 612 - rowid = values[6]; 613 - 614 - pathinfo->time = strtoull(time, NULL, 10); 615 - 616 - /* Package file inodes start at 2^32, fake inodes are before then */ 617 - pathinfo->inode = strtoull(rowid, NULL, 10) + 4294967296ULL; 618 - 619 - if (strcmp(type, "file") == 0) { 620 - pathinfo->type = APPFS_PATHTYPE_FILE; 621 - 622 - if (!size) { 623 - size = "0"; 624 - } 625 - 626 - if (!perms) { 627 - perms = ""; 628 - } 629 - 630 - if (!sha1) { 631 - sha1 = ""; 632 - } 633 - 634 - pathinfo->typeinfo.file.size = strtoull(size, NULL, 10); 635 - snprintf(pathinfo->typeinfo.file.sha1, sizeof(pathinfo->typeinfo.file.sha1), "%s", sha1); 636 - 637 - if (strcmp(perms, "x") == 0) { 638 - pathinfo->typeinfo.file.executable = 1; 639 - } else { 640 - pathinfo->typeinfo.file.executable = 0; 641 - } 642 - 643 - return(0); 644 - } 645 - 646 - if (strcmp(type, "directory") == 0) { 647 - pathinfo->type = APPFS_PATHTYPE_DIRECTORY; 648 - pathinfo->typeinfo.dir.childcount = 0; 649 - 650 - return(0); 651 - } 652 - 653 - if (strcmp(type, "symlink") == 0) { 654 - pathinfo->type = APPFS_PATHTYPE_SYMLINK; 655 - pathinfo->typeinfo.dir.childcount = 0; 656 - 657 - if (!source) { 658 - source = ".BADLINK"; 659 - } 660 - 661 - pathinfo->typeinfo.symlink.size = strlen(source); 662 - snprintf(pathinfo->typeinfo.symlink.source, sizeof(pathinfo->typeinfo.symlink.source), "%s", source); 663 - 664 - return(0); 665 - } 666 - 667 - return(0); 668 - 669 - /* Until this is used, prevent the compiler from complaining */ 670 - source = source; 671 360 } 672 361 673 362 static int appfs_getfileinfo(const char *hostname, const char *package_hash, const char *_path, struct appfs_pathinfo *pathinfo) { 674 - char *directory, *file, *path; 675 - char *sql; 676 - int sqlite_ret; 677 - 678 - if (pathinfo == NULL) { 679 - return(-EIO); 680 - } 681 - 682 - appfs_update_index(hostname); 683 - appfs_update_manifest(hostname, package_hash); 684 - 685 - path = strdup(_path); 686 - directory = path; 687 - file = strrchr(path, '/'); 688 - if (file == NULL) { 689 - file = path; 690 - directory = ""; 691 - } else { 692 - *file = '\0'; 693 - file++; 694 - } 695 - 696 - sql = sqlite3_mprintf("SELECT type, time, source, size, perms, file_sha1, rowid FROM files WHERE package_sha1 = %Q AND file_directory = %Q AND file_name = %Q;", package_hash, directory, file); 697 - if (sql == NULL) { 698 - APPFS_DEBUG("Call to sqlite3_mprintf failed."); 699 - 700 - free(path); 701 - 702 - return(-EIO); 703 - } 704 - 705 - free(path); 706 - 707 - pathinfo->type = APPFS_PATHTYPE_INVALID; 708 - 709 - APPFS_DEBUG("SQL: %s", sql); 710 - sqlite_ret = sqlite3_exec(globalThread.db, sql, appfs_getfileinfo_cb, pathinfo, NULL); 711 - sqlite3_free(sql); 712 - 713 - if (sqlite_ret != SQLITE_OK) { 714 - APPFS_DEBUG("Call to sqlite3_exec failed."); 715 - 716 - return(-EIO); 717 - } 718 - 719 - if (pathinfo->type == APPFS_PATHTYPE_INVALID) { 720 - return(-ENOENT); 721 - } 722 - 723 - return(0); 724 -} 725 - 726 -static int appfs_get_path_info_sql(char *sql, int argc, const char *fmt, struct appfs_pathinfo *pathinfo, struct appfs_children **children) { 727 - struct appfs_children *node, *dir_children, *dir_child; 728 - int dir_children_count = 0; 729 - 730 - dir_children = appfs_sqlite3_query(sql, argc, fmt, &dir_children_count); 731 - 732 - if (dir_children == NULL || dir_children_count == 0) { 733 - return(-ENOENT); 734 - } 735 - 736 - /* Request for a single hostname */ 737 - pathinfo->type = APPFS_PATHTYPE_DIRECTORY; 738 - pathinfo->typeinfo.dir.childcount = dir_children_count; 739 - pathinfo->time = globalThread.boottime; 740 - 741 - if (children) { 742 - for (dir_child = dir_children; dir_child; dir_child = dir_child->_next) { 743 - node = (void *) ckalloc(sizeof(*node)); 744 - node->_next = *children; 745 - strcpy(node->name, dir_child->name); 746 - *children = node; 747 - } 748 - } 749 - 750 - appfs_free_list_children(dir_children); 751 - 752 - return(0); 753 -} 754 - 755 -static int appfs_add_path_child(const char *name, struct appfs_pathinfo *pathinfo, struct appfs_children **children) { 756 - struct appfs_children *new_child; 757 - 758 - pathinfo->typeinfo.dir.childcount++; 759 - 760 - if (children) { 761 - new_child = (void *) ckalloc(sizeof(*new_child)); 762 - new_child->_next = *children; 763 - 764 - snprintf(new_child->name, sizeof(new_child->name), "%s", name); 765 - 766 - *children = new_child; 767 - } 768 - 769 - return(0); 770 363 } 771 364 772 365 /* Generate an inode for a given path */ 773 366 static long long appfs_get_path_inode(const char *path) { 774 367 long long retval; 775 368 const char *p; 776 369 ................................................................................ 786 379 retval %= 4294967296ULL; 787 380 788 381 return(retval); 789 382 } 790 383 791 384 /* Get information about a path, and optionally list children */ 792 385 static int appfs_get_path_info(const char *_path, struct appfs_pathinfo *pathinfo, struct appfs_children **children) { 793 - struct appfs_children *dir_children; 794 - char *hostname, *packagename, *os_cpuArch, *os, *cpuArch, *version; 795 - char *path, *path_s; 796 - char *package_hash; 797 - char *sql; 798 - int files_count; 799 - int fileinfo_ret, retval; 800 - 801 - /* Initialize return */ 802 - if (children) { 803 - *children = NULL; 804 - } 805 - 806 - /* Verify that this is a valid request */ 807 - if (_path == NULL) { 808 - return(-ENOENT); 809 - } 810 - 811 - if (_path[0] != '/') { 812 - return(-ENOENT); 813 - } 814 - 815 - /* Note that this is not a "real" directory from a package */ 816 - pathinfo->packaged = 0; 817 - 818 - if (_path[1] == '\0') { 819 - /* Request for the root directory */ 820 - pathinfo->hostname[0] = '\0'; 821 - pathinfo->inode = 1; 822 - 823 - sql = sqlite3_mprintf("SELECT DISTINCT hostname FROM packages;"); 824 - 825 - retval = appfs_get_path_info_sql(sql, 1, NULL, pathinfo, children); 826 - 827 - /* The root directory always exists, even if it has no subordinates */ 828 - if (retval != 0) { 829 - pathinfo->type = APPFS_PATHTYPE_DIRECTORY; 830 - pathinfo->typeinfo.dir.childcount = 0; 831 - pathinfo->time = globalThread.boottime; 832 - 833 - retval = 0; 834 - } 835 - 836 - return(retval); 837 - } 838 - 839 - path = strdup(_path); 840 - path_s = path; 841 - 842 - pathinfo->inode = appfs_get_path_inode(path); 843 - 844 - hostname = path + 1; 845 - packagename = strchr(hostname, '/'); 846 - 847 - if (packagename != NULL) { 848 - *packagename = '\0'; 849 - packagename++; 850 - } 851 - 852 - snprintf(pathinfo->hostname, sizeof(pathinfo->hostname), "%s", hostname); 853 - 854 - if (packagename == NULL) { 855 - appfs_update_index(hostname); 856 - 857 - sql = sqlite3_mprintf("SELECT DISTINCT package FROM packages WHERE hostname = %Q;", hostname); 858 - 859 - free(path_s); 860 - 861 - return(appfs_get_path_info_sql(sql, 1, NULL, pathinfo, children)); 862 - } 863 - 864 - os_cpuArch = strchr(packagename, '/'); 865 - 866 - if (os_cpuArch != NULL) { 867 - *os_cpuArch = '\0'; 868 - os_cpuArch++; 869 - } 870 - 871 - if (os_cpuArch == NULL) { 872 - appfs_update_index(hostname); 873 - 874 - sql = sqlite3_mprintf("SELECT DISTINCT os, cpuArch FROM packages WHERE hostname = %Q AND package = %Q;", hostname, packagename); 875 - 876 - free(path_s); 877 - 878 - retval = appfs_get_path_info_sql(sql, 2, "%s-%s", pathinfo, children); 879 - 880 - if (retval != 0) { 881 - return(retval); 882 - } 883 - 884 - appfs_add_path_child("platform", pathinfo, children); 885 - 886 - return(retval); 887 - } 888 - 889 - version = strchr(os_cpuArch, '/'); 890 - 891 - if (version != NULL) { 892 - *version = '\0'; 893 - version++; 894 - } 895 - 896 - os = os_cpuArch; 897 - cpuArch = strchr(os_cpuArch, '-'); 898 - if (cpuArch) { 899 - *cpuArch = '\0'; 900 - cpuArch++; 901 - } else { 902 - cpuArch = ""; 903 - } 904 - 905 - if (version == NULL) { 906 - if (strcmp(os, "platform") == 0 && strcmp(cpuArch, "") == 0) { 907 - pathinfo->type = APPFS_PATHTYPE_SYMLINK; 908 - pathinfo->time = globalThread.boottime; 909 - pathinfo->typeinfo.dir.childcount = 0; 910 - pathinfo->typeinfo.symlink.size = strlen(globalThread.platform); 911 - 912 - snprintf(pathinfo->typeinfo.symlink.source, sizeof(pathinfo->typeinfo.symlink.source), "%s", globalThread.platform); 913 - 914 - free(path_s); 915 - 916 - return(0); 917 - } 918 - 919 - /* Request for version list for a package on an OS/CPU */ 920 - appfs_update_index(hostname); 921 - 922 - sql = sqlite3_mprintf("SELECT DISTINCT version FROM packages WHERE hostname = %Q AND package = %Q AND os = %Q and cpuArch = %Q;", hostname, packagename, os, cpuArch); 923 - 924 - free(path_s); 925 - 926 - return(appfs_get_path_info_sql(sql, 1, NULL, pathinfo, children)); 927 - } 928 - 929 - path = strchr(version, '/'); 930 - if (path == NULL) { 931 - path = ""; 932 - } else { 933 - *path = '\0'; 934 - path++; 935 - } 936 - 937 - /* Request for a file in a specific package */ 938 - pathinfo->packaged = 1; 939 - APPFS_DEBUG("Requesting information for hostname = %s, package = %s, os = %s, cpuArch = %s, version = %s, path = %s", 940 - hostname, packagename, os, cpuArch, version, path 941 - ); 942 - 943 - package_hash = appfs_lookup_package_hash(hostname, packagename, os, cpuArch, version); 944 - if (package_hash == NULL) { 945 - free(path_s); 946 - 947 - return(-ENOENT); 948 - } 949 - 950 - APPFS_DEBUG(" ... which hash a hash of %s", package_hash); 951 - 952 - appfs_update_manifest(hostname, package_hash); 953 - 954 - if (strcmp(path, "") == 0) { 955 - pathinfo->type = APPFS_PATHTYPE_DIRECTORY; 956 - pathinfo->time = globalThread.boottime; 957 - } else { 958 - fileinfo_ret = appfs_getfileinfo(hostname, package_hash, path, pathinfo); 959 - if (fileinfo_ret != 0) { 960 - free(path_s); 961 - 962 - return(fileinfo_ret); 963 - } 964 - } 965 - 966 - if (pathinfo->type == APPFS_PATHTYPE_DIRECTORY) { 967 - dir_children = appfs_getchildren(hostname, package_hash, path, &files_count); 968 - 969 - if (dir_children != NULL) { 970 - pathinfo->typeinfo.dir.childcount = files_count; 971 - } 972 - 973 - if (children) { 974 - *children = dir_children; 975 - } else { 976 - appfs_free_list_children(dir_children); 977 - } 978 - } 979 - 980 - free(path_s); 981 - 982 - return(0); 983 -} 984 - 985 -static int appfs_fuse_readlink(const char *path, char *buf, size_t size) { 986 - struct appfs_pathinfo pathinfo; 987 - int res = 0; 988 - 989 - APPFS_DEBUG("Enter (path = %s, ...)", path); 990 - 991 - pathinfo.type = APPFS_PATHTYPE_INVALID; 992 - 993 - res = appfs_get_path_info(path, &pathinfo, NULL); 994 - if (res != 0) { 995 - return(res); 996 - } 997 - 998 - if (pathinfo.type != APPFS_PATHTYPE_SYMLINK) { 999 - return(-EINVAL); 1000 - } 1001 - 1002 - if ((strlen(pathinfo.typeinfo.symlink.source) + 1) > size) { 1003 - return(-ENAMETOOLONG); 1004 - } 1005 - 1006 - memcpy(buf, pathinfo.typeinfo.symlink.source, strlen(pathinfo.typeinfo.symlink.source) + 1); 1007 - 1008 - return(0); 1009 386 } 1010 387 1011 388 static int appfs_fuse_getattr(const char *path, struct stat *stbuf) { 1012 389 struct appfs_pathinfo pathinfo; 1013 390 int res = 0; 1014 391 1015 392 APPFS_DEBUG("Enter (path = %s, ...)", path); ................................................................................ 1156 533 .getattr = appfs_fuse_getattr, 1157 534 .readdir = appfs_fuse_readdir, 1158 535 .readlink = appfs_fuse_readlink, 1159 536 .open = appfs_fuse_open, 1160 537 .release = appfs_fuse_close, 1161 538 .read = appfs_fuse_read 1162 539 }; 540 + 541 +int Appfsd_Init(Tcl_Interp *interp) { 542 +#ifdef USE_TCL_STUBS 543 + if (Tcl_InitStubs(interp, TCL_VERSION, 0) == 0L) { 544 + return(TCL_ERROR); 545 + } 546 +#endif 547 + 548 + Tcl_CreateObjCommand(interp, "appfsd::get_homedir", tcl_appfs_get_homedir, NULL, NULL); 549 + 550 + Tcl_PkgProvide(interp, "appfsd", "1.0"); 551 + 552 + return(TCL_OK); 553 +} 1163 554 1164 555 int main(int argc, char **argv) { 1165 556 const char *cachedir = APPFS_CACHEDIR; 1166 557 char dbfilename[1024]; 1167 - int pthread_ret, snprintf_ret, sqlite_ret; 558 + int pthread_ret, snprintf_ret; 1168 559 1169 560 globalThread.cachedir = cachedir; 1170 561 globalThread.boottime = time(NULL); 1171 - globalThread.platform = "linux-x86_64"; 1172 562 globalThread.options.writable = 1; 1173 563 1174 564 Tcl_StaticPackage(NULL, "sha1", Sha1_Init, NULL); 565 + Tcl_StaticPackage(NULL, "appfsd", Appfsd_Init, NULL); 1175 566 1176 567 pthread_ret = pthread_key_create(&interpKey, NULL); 1177 568 if (pthread_ret != 0) { 1178 569 fprintf(stderr, "Unable to create TSD key for Tcl. Aborting.\n"); 1179 570 1180 571 return(1); 1181 572 } 1182 573 1183 574 snprintf_ret = snprintf(dbfilename, sizeof(dbfilename), "%s/%s", cachedir, "cache.db"); 1184 575 if (snprintf_ret >= sizeof(dbfilename)) { 1185 576 fprintf(stderr, "Unable to set database filename. Aborting.\n"); 1186 577 1187 - return(1); 1188 - } 1189 - 1190 - sqlite_ret = sqlite3_open(dbfilename, &globalThread.db); 1191 - if (sqlite_ret != SQLITE_OK) { 1192 - fprintf(stderr, "Unable to open database: %s\n", dbfilename); 1193 - 1194 578 return(1); 1195 579 } 1196 580 1197 581 return(fuse_main(argc, argv, &appfs_oper, NULL)); 1198 582 } 1199 583