void path_dirname (const char *path, char *dir) { char *c; strcpy(dir, path); /* A trailing slash is semantically important [1] in pathname resolution * because it forces resolution of the final component and that final * component must resolve to a directory. Here, we remove final slashes so * we can get at the containing directory for the final component. * * [1] http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html */ path_remove_trailing_slashes(dir); /* This will be the (possibly one of many) trailing slash for the * containing directory. */ c = strrchr(dir, '/'); if(c) { /* remove all trailing (redundant) slashes */ for (; c >= dir && *c == '/'; c--) *c = 0; if(dir[0] == 0) strcpy(dir, "/"); } else { strcpy(dir, "."); } }
/* Note we need the subject because we must check the ACL for any nested directories. */ INT64_T cfs_basic_search(const char *subject, const char *dir, const char *pattern, int flags, struct link * l, time_t stoptime) { char fullpath[CHIRP_PATH_MAX]; strcpy(fullpath, dir); path_remove_trailing_slashes(fullpath); /* this prevents double slashes from appearing in paths we examine. */ debug(D_DEBUG, "cfs_basic_search(subject = `%s', dir = `%s', pattern = `%s', flags = %d, ...)", subject, dir, pattern, flags); /* FIXME we should still check for literal paths to search since we can optimize that */ return search_directory(subject, fullpath + strlen(fullpath), fullpath, pattern, flags, l, stoptime); }
int disk_alloc_create(char *loc, char *fs, int64_t size) { if(size <= 0) { debug(D_NOTICE, "Mountpoint pathname argument nonexistant.\n"); return 1; } //Check for trailing '/' path_remove_trailing_slashes(loc); int result; char *device_loc = NULL; char *dd_args = NULL; char *losetup_args = NULL; char *mk_args = NULL; char *mount_args = NULL; //Set Loopback Device Location device_loc = string_format("%s/alloc.img", loc); //Make Directory for Loop Device if(mkdir(loc, 0777) != 0) { debug(D_NOTICE, "Failed to make directory at requested mountpoint: %s.\n", strerror(errno)); goto error; } //Create Image dd_args = string_format("dd if=/dev/zero of=%s bs=1024 count=%"PRId64"", device_loc, size); if(system(dd_args) != 0) { debug(D_NOTICE, "Failed to allocate junk space for loop device image: %s.\n", strerror(errno)); if(unlink(device_loc) == -1) { debug(D_NOTICE, "Failed to unlink loop device image while attempting to clean up after failure: %s.\n", strerror(errno)); goto error; } if(rmdir(loc) == -1) { debug(D_NOTICE, "Failed to remove directory of loop device image while attempting to clean up after failure: %s.\n", strerror(errno)); } goto error; } //Attach Image to Loop Device int j, losetup_flag = 0; for(j = 0; ; j++) { if(j >= 256) { losetup_flag = 1; break; } losetup_args = string_format("losetup /dev/loop%d %s", j, device_loc); mk_args = string_format("mkfs /dev/loop%d", j); mount_args = string_format("/dev/loop%d", j); if(system(losetup_args) == 0) { break; } } if(losetup_flag == 1) { debug(D_NOTICE, "Failed to attach image to loop device: %s.\n", strerror(errno)); if(unlink(device_loc) == -1) { debug(D_NOTICE, "Failed to unlink loop device image while attempting to clean up after failure: %s.\n", strerror(errno)); goto error; } if(rmdir(loc) == -1) { debug(D_NOTICE, "Failed to remove directory of loop device image while attempting to clean up after failure: %s.\n", strerror(errno)); } goto error; } //Create Filesystem if(system(mk_args) != 0) { char *rm_dir_args; debug(D_NOTICE, "Failed to initialize filesystem on loop device: %s.\n", strerror(errno)); rm_dir_args = string_format("losetup -d /dev/loop%d; rm -r %s", j, loc); if(system(rm_dir_args) == -1) { debug(D_NOTICE, "Failed to detach loop device and remove its contents while attempting to clean up after failure: %s.\n", strerror(errno)); } free(rm_dir_args); goto error; } //Mount Loop Device result = mount(mount_args, loc, fs, 0, ""); if(result != 0) { char *rm_dir_args; debug(D_NOTICE, "Failed to mount loop device: %s.\n", strerror(errno)); rm_dir_args = string_format("losetup -d /dev/loop%d; rm -r %s", j, loc); if(system(rm_dir_args) == -1) { debug(D_NOTICE, "Failed to detach loop device and remove its contents while attempting to clean up after failure: %s.\n", strerror(errno)); } free(rm_dir_args); goto error; } free(device_loc); free(dd_args); free(losetup_args); free(mk_args); free(mount_args); return 0; error: if(device_loc) { free(device_loc); } if(dd_args) { free(dd_args); } if(losetup_args) { free(losetup_args); } if(mk_args) { free(mk_args); } if(mount_args) { free(mount_args); } return 1; }
int disk_alloc_delete(char *loc) { int result; char *losetup_args = NULL; char *rm_args = NULL; char *device_loc = NULL; char *losetup_del_args = NULL; //Check for trailing '/' path_remove_trailing_slashes(loc); //Check if location is relative or absolute result = strncmp(loc, "/", 1); if(result != 0) { char *pwd = get_current_dir_name(); path_remove_trailing_slashes(pwd); device_loc = string_format("%s/%s/alloc.img", pwd, loc); free(pwd); } else { device_loc = string_format("%s/alloc.img", loc); } //Find Used Device char *dev_num = "-1"; //Loop Device Unmounted result = umount2(loc, MNT_FORCE); if(result != 0) { if(errno != ENOENT) { debug(D_NOTICE, "Failed to unmount loop device: %s.\n", strerror(errno)); goto error; } } //Find pathname of mountpoint associated with loop device char loop_dev[128], loop_info[128], loop_mount[128]; FILE *loop_find; losetup_args = string_format("losetup -j %s", device_loc); loop_find = popen(losetup_args, "r"); fscanf(loop_find, "%s %s %s", loop_dev, loop_info, loop_mount); pclose(loop_find); int loop_dev_path_length = strlen(loop_mount); loop_mount[loop_dev_path_length - 1] = '\0'; loop_dev[strlen(loop_dev) - 1] = '\0'; char loop_mountpoint_array[128]; int k; int max_mount_path_length = 62; //Copy only pathname of the mountpoint without extraneous paretheses for(k = 1; k < loop_dev_path_length; k++) { loop_mountpoint_array[k-1] = loop_mount[k]; } loop_mountpoint_array[k] = '\0'; if(strncmp(loop_mountpoint_array, device_loc, max_mount_path_length) == 0) { dev_num = loop_dev; } //Device Not Found if(strcmp(dev_num, "-1") == 0) { debug(D_NOTICE, "Failed to locate loop device associated with given mountpoint: %s.\n", strerror(errno)); goto error; } rm_args = string_format("%s/alloc.img", loc); losetup_del_args = string_format("losetup -d %s", dev_num); //Loop Device Deleted result = system(losetup_del_args); if(result != 0) { if(errno != ENOENT) { debug(D_NOTICE, "Failed to remove loop device associated with given mountpoint: %s.\n", strerror(errno)); goto error; } } //Image Deleted result = unlink(rm_args); if(result != 0) { debug(D_NOTICE, "Failed to delete image file associated with given mountpoint: %s.\n", strerror(errno)); goto error; } //Directory Deleted result = rmdir(loc); if(result != 0) { debug(D_NOTICE, "Failed to delete directory associated with given mountpoint: %s.\n", strerror(errno)); goto error; } free(losetup_del_args); free(losetup_args); free(rm_args); free(device_loc); return 0; error: if(losetup_del_args) { free(losetup_del_args); } if(losetup_args) { free(losetup_args); } if(rm_args) { free(rm_args); } if(device_loc) { free(device_loc); } return 1; }