static int fuse_link(const char* from, const char* to) { PRINTD("##link\n"); return _ERR(_kern_create_link(to, from)); }
static fssh_status_t command_ln(int argc, const char* const* argv) { bool force = false; bool symbolic = false; bool dereference = true; // parse parameters int argi = 1; for (argi = 1; argi < argc; argi++) { const char *arg = argv[argi]; if (arg[0] != '-') break; if (arg[1] == '\0') { fprintf(stderr, "Error: Invalid option \"-\"\n"); return FSSH_B_BAD_VALUE; } for (int i = 1; arg[i]; i++) { switch (arg[i]) { case 'f': force = true; break; case 's': symbolic = true; break; case 'n': dereference = false; break; default: fprintf(stderr, "Error: Unknown option \"-%c\"\n", arg[i]); return FSSH_B_BAD_VALUE; } } } if (argc - argi != 2) { fprintf(stderr, "Usage: %s [Options] <source> <target>\n", argv[0]); return FSSH_B_BAD_VALUE; } const char *source = argv[argi]; const char *target = argv[argi + 1]; // check, if the the target is an existing directory struct fssh_stat st; char targetBuffer[FSSH_B_PATH_NAME_LENGTH]; fssh_status_t error = _kern_read_stat(-1, target, dereference, &st, sizeof(st)); if (error == FSSH_B_OK) { if (FSSH_S_ISDIR(st.fssh_st_mode)) { // get source leaf char leaf[FSSH_B_FILE_NAME_LENGTH]; error = get_last_path_component(source, leaf, sizeof(leaf)); if (error != FSSH_B_OK) { fprintf(stderr, "Error: Failed to get leaf name of source " "path: %s\n", fssh_strerror(error)); return error; } // compose a new path int len = strlen(target) + 1 + strlen(leaf); if (len > (int)sizeof(targetBuffer)) { fprintf(stderr, "Error: Resulting target path is too long.\n"); return FSSH_B_BAD_VALUE; } strcpy(targetBuffer, target); strcat(targetBuffer, "/"); strcat(targetBuffer, leaf); target = targetBuffer; } } // check, if the target exists error = _kern_read_stat(-1, target, false, &st, sizeof(st)); if (error == FSSH_B_OK) { if (!force) { fprintf(stderr, "Error: Can't create link. \"%s\" is in the way.\n", target); return FSSH_B_FILE_EXISTS; } // unlink the entry error = _kern_unlink(-1, target); if (error != FSSH_B_OK) { fprintf(stderr, "Error: Failed to remove \"%s\" to make way for " "link: %s\n", target, fssh_strerror(error)); return error; } } // finally create the link if (symbolic) { error = _kern_create_symlink(-1, target, source, FSSH_S_IRWXU | FSSH_S_IRWXG | FSSH_S_IRWXO); } else error = _kern_create_link(target, source); if (error != FSSH_B_OK) { fprintf(stderr, "Error: Failed to create link: %s\n", fssh_strerror(error)); } return error; }