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 14 static const uint32 kMountPermission = MOUNT_SHARE_PERMISSION; 15 static const uint32 kQueryPermission = QUERY_SHARE_PERMISSION; 16 static const uint32 kReadPermission 17 = READ_PERMISSION | READ_DIR_PERMISSION | RESOLVE_DIR_ENTRY_PERMISSION; 18 static const uint32 kWritePermission 19 = WRITE_PERMISSION | WRITE_DIR_PERMISSION; 20 21 // usage 22 static 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 52 static 53 void 54 print_usage(bool error) 55 { 56 fputs(kUsage, (error ? stderr : stdout)); 57 } 58 59 // print_usage_and_exit 60 static 61 void 62 print_usage_and_exit(bool error) 63 { 64 print_usage(error); 65 exit(error ? 1 : 0); 66 } 67 68 // get_permissions_string 69 static 70 void 71 get_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 81 static 82 bool 83 get_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 114 static 115 void 116 assert_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 127 static 128 void 129 list() 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 211 static 212 void 213 add_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 235 static 236 void 237 remove_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 259 static 260 void 261 add_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 283 static 284 void 285 remove_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 307 static 308 void 309 set_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 337 static 338 void 339 launch_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 356 static 357 void 358 terminate_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 372 static 373 void 374 save_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 388 static 389 const char* 390 next_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 402 static 403 void 404 no_more_args(int argc, int argi) 405 { 406 if (argi < argc) 407 print_usage_and_exit(true); 408 } 409 410 // main 411 int 412 main(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