1// NetFSServerPrefs.cpp 2 3#include <stdio.h> 4#include <stdlib.h> 5#include <string.h> 6 7#include <Application.h> 8#include <Message.h> 9 10#include "NetFSServerRoster.h" 11#include "Permissions.h" 12 13// simplified permissions 14static const uint32 kMountPermission = MOUNT_SHARE_PERMISSION; 15static const uint32 kQueryPermission = QUERY_SHARE_PERMISSION; 16static const uint32 kReadPermission 17 = READ_PERMISSION | READ_DIR_PERMISSION | RESOLVE_DIR_ENTRY_PERMISSION; 18static const uint32 kWritePermission 19 = WRITE_PERMISSION | WRITE_DIR_PERMISSION; 20 21// usage 22static const char* kUsage = 23"Usage: netfs_server_prefs -h | --help\n" 24" netfs_server_prefs <command>\n" 25"options:\n" 26" -h, --help - print this text\n" 27"\n" 28"commands:\n" 29" launch\n" 30" launches the server\n" 31" terminate\n" 32" terminates the server\n" 33" save\n" 34" saves the server settings\n" 35" l, list\n" 36" list all users and all shares\n" 37" add share <name> <path>\n" 38" add a new share with the name <name> and path <path>\n" 39" remove share <name>\n" 40" remove the share named <name>\n" 41" add user <name> [ <password> ]\n" 42" add a new user with the name <name> and, if supplied, \n" 43" password <password>\n" 44" remove user <name>\n" 45" remove the user named <name>\n" 46" permissions <user> <share> [ m ] [ r ] [ w ] [ q ]\n" 47" set the permissions of user <user> for share <share> to m(ount),\n" 48" r(ead), w(rite), and/or q(uery).\n" 49; 50 51// print_usage 52static 53void 54print_usage(bool error) 55{ 56 fputs(kUsage, (error ? stderr : stdout)); 57} 58 59// print_usage_and_exit 60static 61void 62print_usage_and_exit(bool error) 63{ 64 print_usage(error); 65 exit(error ? 1 : 0); 66} 67 68// get_permissions_string 69static 70void 71get_permissions_string(uint32 permissions, char* str) 72{ 73 str[0] = (permissions & kMountPermission ? 'm' : '-'); 74 str[1] = (permissions & kReadPermission ? 'r' : '-'); 75 str[2] = (permissions & kWritePermission ? 'w' : '-'); 76 str[3] = (permissions & kQueryPermission ? 'q' : '-'); 77 str[4] = '\0'; 78} 79 80// get_permissions 81static 82bool 83get_permissions(const char* str, uint32* permissions) 84{ 85 *permissions = 0; 86 87 if (!str) 88 return true; 89 90 while (*str) { 91 switch (*str) { 92 case 'm': 93 *permissions |= kMountPermission; 94 break; 95 case 'r': 96 *permissions |= kReadPermission; 97 break; 98 case 'w': 99 *permissions |= kWritePermission; 100 break; 101 case 'q': 102 *permissions |= kQueryPermission; 103 break; 104 default: 105 return false; 106 } 107 str++; 108 } 109 110 return true; 111} 112 113// assert_server_running 114static 115void 116assert_server_running() 117{ 118 // check, if the server is running 119 NetFSServerRoster roster; 120 if (!roster.IsServerRunning()) { 121 fprintf(stderr, "Server is not running.\n"); 122 exit(1); 123 } 124} 125 126// list 127static 128void 129list() 130{ 131 assert_server_running(); 132 133 NetFSServerRoster roster; 134 135 // get the users 136 BMessage users; 137 status_t error = roster.GetUsers(&users); 138 if (error == B_OK) { 139 // list the users 140 printf("users\n"); 141 printf("-----\n"); 142 const char* user; 143 for (int32 i = 0; users.FindString("users", i, &user) == B_OK; i++) 144 printf("%s\n", user); 145 printf("\n"); 146 } else 147 fprintf(stderr, "Failed to get users: %s\n", strerror(error)); 148 149 // get the shares 150 BMessage shares; 151 error = roster.GetShares(&shares); 152 if (error == B_OK) { 153 // list the shares 154 printf("shares\n"); 155 printf("------\n"); 156 const char* share; 157 for (int32 i = 0; shares.FindString("shares", i, &share) == B_OK; i++) { 158 // get path 159 const char* path; 160 if (shares.FindString("paths", i, &path) != B_OK) 161 path = "<invalid path>\n"; 162 163 // get share users 164 BMessage shareUsers; 165 roster.GetShareUsers(share, &shareUsers); 166 167 // get statistics 168 BMessage statistics; 169 roster.GetShareStatistics(share, &statistics); 170 171 printf("%s:\n", share); 172 printf(" path: %s\n", path); 173 174 // print permitted users 175 printf(" mountable by: "); 176 const char* user; 177 for (int32 k = 0; 178 shareUsers.FindString("users", k, &user) == B_OK; 179 k++) { 180 if (k > 0) 181 printf(", "); 182 printf("%s", user); 183 184 // print permissions 185 uint32 permissions = 0; 186 roster.GetUserPermissions(share, user, &permissions); 187 char permissionsString[8]; 188 get_permissions_string(permissions, permissionsString); 189 printf(" (%s)", permissionsString); 190 } 191 printf("\n"); 192 193 // print current users 194 printf(" mounted by: "); 195 for (int32 k = 0; 196 statistics.FindString("mounted by", k, &user) == B_OK; 197 k++) { 198 if (k > 0) 199 printf(", "); 200 printf("%s", user); 201 } 202 printf("\n"); 203 204 printf("\n"); 205 } 206 } else 207 fprintf(stderr, "Failed to get users: %s\n", strerror(error)); 208} 209 210// add_share 211static 212void 213add_share(const char* name, const char* path) 214{ 215 assert_server_running(); 216 217 NetFSServerRoster roster; 218 219 // check whether a share with the given name already exists 220 BMessage statistics; 221 if (roster.GetShareStatistics(name, &statistics) == B_OK) { 222 fprintf(stderr, "A share `%s' does already exist.\n", name); 223 exit(1); 224 } 225 226 // add the share 227 status_t error = roster.AddShare(name, path); 228 if (error != B_OK) { 229 fprintf(stderr, "Failed to add share: %s\n", strerror(error)); 230 exit(1); 231 } 232} 233 234// remove_share 235static 236void 237remove_share(const char* name) 238{ 239 assert_server_running(); 240 241 NetFSServerRoster roster; 242 243 // check whether a share with the given name exists 244 BMessage statistics; 245 if (roster.GetShareStatistics(name, &statistics) != B_OK) { 246 fprintf(stderr, "A share `%s' does not exist.\n", name); 247 exit(1); 248 } 249 250 // remove the share 251 status_t error = roster.RemoveShare(name); 252 if (error != B_OK) { 253 fprintf(stderr, "Failed to remove share: %s\n", strerror(error)); 254 exit(1); 255 } 256} 257 258// add_user 259static 260void 261add_user(const char* name, const char* password) 262{ 263 assert_server_running(); 264 265 NetFSServerRoster roster; 266 267 // check whether a user with the given name already exists 268 BMessage statistics; 269 if (roster.GetUserStatistics(name, &statistics) == B_OK) { 270 fprintf(stderr, "A user `%s' does already exist.\n", name); 271 exit(1); 272 } 273 274 // add the user 275 status_t error = roster.AddUser(name, password); 276 if (error != B_OK) { 277 fprintf(stderr, "Failed to add user: %s\n", strerror(error)); 278 exit(1); 279 } 280} 281 282// remove_user 283static 284void 285remove_user(const char* name) 286{ 287 assert_server_running(); 288 289 NetFSServerRoster roster; 290 291 // check whether a user with the given name exists 292 BMessage statistics; 293 if (roster.GetUserStatistics(name, &statistics) != B_OK) { 294 fprintf(stderr, "A user `%s' does not exist.\n", name); 295 exit(1); 296 } 297 298 // remove the user 299 status_t error = roster.RemoveUser(name); 300 if (error != B_OK) { 301 fprintf(stderr, "Failed to remove user: %s\n", strerror(error)); 302 exit(1); 303 } 304} 305 306// set_user_permissions 307static 308void 309set_user_permissions(const char* user, const char* share, uint32 permissions) 310{ 311 assert_server_running(); 312 313 NetFSServerRoster roster; 314 315 // check whether a user with the given name exists 316 BMessage statistics; 317 if (roster.GetUserStatistics(user, &statistics) != B_OK) { 318 fprintf(stderr, "A user `%s' does not exist.\n", user); 319 exit(1); 320 } 321 322 // check whether a share with the given name exists 323 if (roster.GetShareStatistics(share, &statistics) != B_OK) { 324 fprintf(stderr, "A share `%s' does not exist.\n", share); 325 exit(1); 326 } 327 328 // set the permissions 329 status_t error = roster.SetUserPermissions(share, user, permissions); 330 if (error != B_OK) { 331 fprintf(stderr, "Failed to set permissions: %s\n", strerror(error)); 332 exit(1); 333 } 334} 335 336// launch_server 337static 338void 339launch_server() 340{ 341 NetFSServerRoster roster; 342 343 if (roster.IsServerRunning()) { 344 fprintf(stderr, "Server is already running.\n"); 345 exit(1); 346 } 347 348 status_t error = roster.LaunchServer(); 349 if (error != B_OK) { 350 fprintf(stderr, "Failed to launch server: %s\n", strerror(error)); 351 exit(1); 352 } 353} 354 355// terminate_server 356static 357void 358terminate_server() 359{ 360 assert_server_running(); 361 362 NetFSServerRoster roster; 363 364 status_t error = roster.TerminateServer(); 365 if (error != B_OK) { 366 fprintf(stderr, "Failed to terminate server: %s\n", strerror(error)); 367 exit(1); 368 } 369} 370 371// save_server_setttings 372static 373void 374save_server_setttings() 375{ 376 assert_server_running(); 377 378 NetFSServerRoster roster; 379 380 status_t error = roster.SaveServerSettings(); 381 if (error != B_OK) { 382 fprintf(stderr, "Failed to save settings: %s\n", strerror(error)); 383 exit(1); 384 } 385} 386 387// next_arg 388static 389const char* 390next_arg(int argc, char** argv, int& argi, bool dontFail = false) 391{ 392 if (argi >= argc) { 393 if (dontFail) 394 return NULL; 395 print_usage_and_exit(true); 396 } 397 398 return argv[argi++]; 399} 400 401// no_more_args 402static 403void 404no_more_args(int argc, int argi) 405{ 406 if (argi < argc) 407 print_usage_and_exit(true); 408} 409 410// main 411int 412main(int argc, char** argv) 413{ 414 BApplication app("application/x-vnd.haiku-netfs_server_prefs"); 415 416 // parse first argument 417 int argi = 1; 418 const char* arg = next_arg(argc, argv, argi); 419 if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) 420 print_usage_and_exit(false); 421 422 if (strcmp(arg, "launch") == 0) { 423 // launch 424 no_more_args(argc, argi); 425 launch_server(); 426 } else if (strcmp(arg, "terminate") == 0) { 427 // terminate 428 no_more_args(argc, argi); 429 terminate_server(); 430 } else if (strcmp(arg, "save") == 0) { 431 // save 432 no_more_args(argc, argi); 433 save_server_setttings(); 434 } else if (strcmp(arg, "l") == 0 || strcmp(arg, "list") == 0) { 435 // list 436 no_more_args(argc, argi); 437 list(); 438 } else if (strcmp(arg, "add") == 0) { 439 // add 440 arg = next_arg(argc, argv, argi); 441 if (strcmp(arg, "share") == 0) { 442 // share 443 const char* name = next_arg(argc, argv, argi); 444 const char* path = next_arg(argc, argv, argi); 445 no_more_args(argc, argi); 446 add_share(name, path); 447 } else if (strcmp(arg, "user") == 0) { 448 // user 449 const char* name = next_arg(argc, argv, argi); 450 const char* password = next_arg(argc, argv, argi, true); 451 no_more_args(argc, argi); 452 add_user(name, password); 453 } else 454 print_usage_and_exit(true); 455 } else if (strcmp(arg, "remove") == 0) { 456 // remove 457 arg = next_arg(argc, argv, argi); 458 if (strcmp(arg, "share") == 0) { 459 // share 460 const char* name = next_arg(argc, argv, argi); 461 no_more_args(argc, argi); 462 remove_share(name); 463 } else if (strcmp(arg, "user") == 0) { 464 // user 465 const char* name = next_arg(argc, argv, argi); 466 no_more_args(argc, argi); 467 remove_user(name); 468 } else 469 print_usage_and_exit(true); 470 } else if (strcmp(arg, "permissions") == 0) { 471 // permissions 472 const char* user = next_arg(argc, argv, argi); 473 const char* share = next_arg(argc, argv, argi); 474 uint32 permissions = 0; 475 while (argi < argc) { 476 uint32 perms = 0; 477 arg = next_arg(argc, argv, argi); 478 if (!get_permissions(arg, &perms)) 479 print_usage_and_exit(true); 480 permissions |= perms; 481 } 482 set_user_permissions(user, share, permissions); 483 } else { 484 print_usage_and_exit(true); 485 } 486 487 return 0; 488} 489