// NetFSServerPrefs.cpp #include #include #include #include #include #include "NetFSServerRoster.h" #include "Permissions.h" // simplified permissions static const uint32 kMountPermission = MOUNT_SHARE_PERMISSION; static const uint32 kQueryPermission = QUERY_SHARE_PERMISSION; static const uint32 kReadPermission = READ_PERMISSION | READ_DIR_PERMISSION | RESOLVE_DIR_ENTRY_PERMISSION; static const uint32 kWritePermission = WRITE_PERMISSION | WRITE_DIR_PERMISSION; // usage static const char* kUsage = "Usage: netfs_server_prefs -h | --help\n" " netfs_server_prefs \n" "options:\n" " -h, --help - print this text\n" "\n" "commands:\n" " launch\n" " launches the server\n" " terminate\n" " terminates the server\n" " save\n" " saves the server settings\n" " l, list\n" " list all users and all shares\n" " add share \n" " add a new share with the name and path \n" " remove share \n" " remove the share named \n" " add user [ ]\n" " add a new user with the name and, if supplied, \n" " password \n" " remove user \n" " remove the user named \n" " permissions [ m ] [ r ] [ w ] [ q ]\n" " set the permissions of user for share to m(ount),\n" " r(ead), w(rite), and/or q(uery).\n" ; // print_usage static void print_usage(bool error) { fputs(kUsage, (error ? stderr : stdout)); } // print_usage_and_exit static void print_usage_and_exit(bool error) { print_usage(error); exit(error ? 1 : 0); } // get_permissions_string static void get_permissions_string(uint32 permissions, char* str) { str[0] = (permissions & kMountPermission ? 'm' : '-'); str[1] = (permissions & kReadPermission ? 'r' : '-'); str[2] = (permissions & kWritePermission ? 'w' : '-'); str[3] = (permissions & kQueryPermission ? 'q' : '-'); str[4] = '\0'; } // get_permissions static bool get_permissions(const char* str, uint32* permissions) { *permissions = 0; if (!str) return true; while (*str) { switch (*str) { case 'm': *permissions |= kMountPermission; break; case 'r': *permissions |= kReadPermission; break; case 'w': *permissions |= kWritePermission; break; case 'q': *permissions |= kQueryPermission; break; default: return false; } str++; } return true; } // assert_server_running static void assert_server_running() { // check, if the server is running NetFSServerRoster roster; if (!roster.IsServerRunning()) { fprintf(stderr, "Server is not running.\n"); exit(1); } } // list static void list() { assert_server_running(); NetFSServerRoster roster; // get the users BMessage users; status_t error = roster.GetUsers(&users); if (error == B_OK) { // list the users printf("users\n"); printf("-----\n"); const char* user; for (int32 i = 0; users.FindString("users", i, &user) == B_OK; i++) printf("%s\n", user); printf("\n"); } else fprintf(stderr, "Failed to get users: %s\n", strerror(error)); // get the shares BMessage shares; error = roster.GetShares(&shares); if (error == B_OK) { // list the shares printf("shares\n"); printf("------\n"); const char* share; for (int32 i = 0; shares.FindString("shares", i, &share) == B_OK; i++) { // get path const char* path; if (shares.FindString("paths", i, &path) != B_OK) path = "\n"; // get share users BMessage shareUsers; roster.GetShareUsers(share, &shareUsers); // get statistics BMessage statistics; roster.GetShareStatistics(share, &statistics); printf("%s:\n", share); printf(" path: %s\n", path); // print permitted users printf(" mountable by: "); const char* user; for (int32 k = 0; shareUsers.FindString("users", k, &user) == B_OK; k++) { if (k > 0) printf(", "); printf("%s", user); // print permissions uint32 permissions = 0; roster.GetUserPermissions(share, user, &permissions); char permissionsString[8]; get_permissions_string(permissions, permissionsString); printf(" (%s)", permissionsString); } printf("\n"); // print current users printf(" mounted by: "); for (int32 k = 0; statistics.FindString("mounted by", k, &user) == B_OK; k++) { if (k > 0) printf(", "); printf("%s", user); } printf("\n"); printf("\n"); } } else fprintf(stderr, "Failed to get users: %s\n", strerror(error)); } // add_share static void add_share(const char* name, const char* path) { assert_server_running(); NetFSServerRoster roster; // check whether a share with the given name already exists BMessage statistics; if (roster.GetShareStatistics(name, &statistics) == B_OK) { fprintf(stderr, "A share `%s' does already exist.\n", name); exit(1); } // add the share status_t error = roster.AddShare(name, path); if (error != B_OK) { fprintf(stderr, "Failed to add share: %s\n", strerror(error)); exit(1); } } // remove_share static void remove_share(const char* name) { assert_server_running(); NetFSServerRoster roster; // check whether a share with the given name exists BMessage statistics; if (roster.GetShareStatistics(name, &statistics) != B_OK) { fprintf(stderr, "A share `%s' does not exist.\n", name); exit(1); } // remove the share status_t error = roster.RemoveShare(name); if (error != B_OK) { fprintf(stderr, "Failed to remove share: %s\n", strerror(error)); exit(1); } } // add_user static void add_user(const char* name, const char* password) { assert_server_running(); NetFSServerRoster roster; // check whether a user with the given name already exists BMessage statistics; if (roster.GetUserStatistics(name, &statistics) == B_OK) { fprintf(stderr, "A user `%s' does already exist.\n", name); exit(1); } // add the user status_t error = roster.AddUser(name, password); if (error != B_OK) { fprintf(stderr, "Failed to add user: %s\n", strerror(error)); exit(1); } } // remove_user static void remove_user(const char* name) { assert_server_running(); NetFSServerRoster roster; // check whether a user with the given name exists BMessage statistics; if (roster.GetUserStatistics(name, &statistics) != B_OK) { fprintf(stderr, "A user `%s' does not exist.\n", name); exit(1); } // remove the user status_t error = roster.RemoveUser(name); if (error != B_OK) { fprintf(stderr, "Failed to remove user: %s\n", strerror(error)); exit(1); } } // set_user_permissions static void set_user_permissions(const char* user, const char* share, uint32 permissions) { assert_server_running(); NetFSServerRoster roster; // check whether a user with the given name exists BMessage statistics; if (roster.GetUserStatistics(user, &statistics) != B_OK) { fprintf(stderr, "A user `%s' does not exist.\n", user); exit(1); } // check whether a share with the given name exists if (roster.GetShareStatistics(share, &statistics) != B_OK) { fprintf(stderr, "A share `%s' does not exist.\n", share); exit(1); } // set the permissions status_t error = roster.SetUserPermissions(share, user, permissions); if (error != B_OK) { fprintf(stderr, "Failed to set permissions: %s\n", strerror(error)); exit(1); } } // launch_server static void launch_server() { NetFSServerRoster roster; if (roster.IsServerRunning()) { fprintf(stderr, "Server is already running.\n"); exit(1); } status_t error = roster.LaunchServer(); if (error != B_OK) { fprintf(stderr, "Failed to launch server: %s\n", strerror(error)); exit(1); } } // terminate_server static void terminate_server() { assert_server_running(); NetFSServerRoster roster; status_t error = roster.TerminateServer(); if (error != B_OK) { fprintf(stderr, "Failed to terminate server: %s\n", strerror(error)); exit(1); } } // save_server_setttings static void save_server_setttings() { assert_server_running(); NetFSServerRoster roster; status_t error = roster.SaveServerSettings(); if (error != B_OK) { fprintf(stderr, "Failed to save settings: %s\n", strerror(error)); exit(1); } } // next_arg static const char* next_arg(int argc, char** argv, int& argi, bool dontFail = false) { if (argi >= argc) { if (dontFail) return NULL; print_usage_and_exit(true); } return argv[argi++]; } // no_more_args static void no_more_args(int argc, int argi) { if (argi < argc) print_usage_and_exit(true); } // main int main(int argc, char** argv) { BApplication app("application/x-vnd.haiku-netfs_server_prefs"); // parse first argument int argi = 1; const char* arg = next_arg(argc, argv, argi); if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) print_usage_and_exit(false); if (strcmp(arg, "launch") == 0) { // launch no_more_args(argc, argi); launch_server(); } else if (strcmp(arg, "terminate") == 0) { // terminate no_more_args(argc, argi); terminate_server(); } else if (strcmp(arg, "save") == 0) { // save no_more_args(argc, argi); save_server_setttings(); } else if (strcmp(arg, "l") == 0 || strcmp(arg, "list") == 0) { // list no_more_args(argc, argi); list(); } else if (strcmp(arg, "add") == 0) { // add arg = next_arg(argc, argv, argi); if (strcmp(arg, "share") == 0) { // share const char* name = next_arg(argc, argv, argi); const char* path = next_arg(argc, argv, argi); no_more_args(argc, argi); add_share(name, path); } else if (strcmp(arg, "user") == 0) { // user const char* name = next_arg(argc, argv, argi); const char* password = next_arg(argc, argv, argi, true); no_more_args(argc, argi); add_user(name, password); } else print_usage_and_exit(true); } else if (strcmp(arg, "remove") == 0) { // remove arg = next_arg(argc, argv, argi); if (strcmp(arg, "share") == 0) { // share const char* name = next_arg(argc, argv, argi); no_more_args(argc, argi); remove_share(name); } else if (strcmp(arg, "user") == 0) { // user const char* name = next_arg(argc, argv, argi); no_more_args(argc, argi); remove_user(name); } else print_usage_and_exit(true); } else if (strcmp(arg, "permissions") == 0) { // permissions const char* user = next_arg(argc, argv, argi); const char* share = next_arg(argc, argv, argi); uint32 permissions = 0; while (argi < argc) { uint32 perms = 0; arg = next_arg(argc, argv, argi); if (!get_permissions(arg, &perms)) print_usage_and_exit(true); permissions |= perms; } set_user_permissions(user, share, permissions); } else { print_usage_and_exit(true); } return 0; }