📄 filesystem.c
字号:
#include <pwd.h>#include <stddef.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <dirent.h>#include <unistd.h>#include "filesystem.h"FileSystem::FileSystem(int need_home){ if(need_home) {// ========================= set to user's home directory uid_t uid; struct passwd *pw; uid = getuid(); /* get user id */ pw = getpwuid(uid); /* get info for user */ sprintf(current_dir, "%s", pw->pw_dir);// ========================= set to current directory //getcwd(current_dir, 1024); } show_all_files = 0; want_directory = 0; total_files = 0; strcpy(filter, "");}FileSystem::~FileSystem(){ for(int i = 0; i < total_files; i++) { delete dir_list[i]; }}FileSystem::compare(const char *c1, const char *c2){ return strcmp (c1, c2);}FileSystem::sort(){ int changed; char *temp; changed = 1; while(changed) { changed = 0; for(int i = 0; i < total_files - 1; i++) { if(strcmp(dir_list[i], dir_list[i + 1]) > 0) { temp = dir_list[i]; dir_list[i] = dir_list[i+1]; dir_list[i+1] = temp; changed = 1; } } }}FileSystem::update(char *new_dir){ DIR *dirstream; struct dirent *filename_; struct stat ostat; int i, result, j, k; int is_directory; char string[256], string2[256];// erase old directory for(i = 0; i < total_files; i++) { delete dir_list[i]; } total_files = 0; /* get totaldirentries and filenames */ if(new_dir != 0) strcpy(current_dir, new_dir); dirstream = opendir(current_dir); /* read directory */ if(!dirstream) return 1; // failed to open directory while ((filename_ = readdir(dirstream)) && total_files < 1000) { result = 1; is_directory = 0;// file not hidden if(!strcmp(filename_->d_name, "..") || filename_->d_name[0] != '.' || (show_all_files && strcmp(filename_->d_name, "."))) { // add 2 in case it is a directory sprintf(string, "%s", current_dir); if(strcmp(current_dir, "/")) strcat(string, "/"); strcat(string, filename_->d_name); sprintf(string2, "%s", filename_->d_name);// test directory if(!stat(string, &ostat) && S_ISDIR(ostat.st_mode)) { strcat(string2, "/"); // is a directory is_directory = 1; result = 0; }// test filter if(result) { for(j = strlen(string2) - 1, k = strlen(filter) - 1; j > 0 && k > 0 && string2[j] == filter[k]; j--, k--) { ; } if(k == 0 || filter[0] == 0) result = 0; }// test want_directory if(want_directory && !is_directory) result = 1;// add to list if(!result) { dir_list[total_files] = new char[strlen(string2) + 1]; strcpy(dir_list[total_files], string2); total_files++; } } } closedir(dirstream); sort(); return 0; // success}FileSystem::set_filter(char *new_filter){ strcpy(filter, new_filter);}FileSystem::set_show_all(){ show_all_files = 1;}FileSystem::set_want_directory(){ want_directory = 1;}FileSystem::is_dir(char *new_dir_) // return 0 if the text is a directory{ if(!strlen(new_dir_)) return 1; static char new_dir[1024]; strcpy(new_dir, new_dir_); complete_path(new_dir); struct stat ostat; // entire name is a directory if(!stat(new_dir, &ostat) && S_ISDIR(ostat.st_mode)) return 0; return 1;}FileSystem::create_dir(char *new_dir_){ char new_dir[1024]; strcpy(new_dir, new_dir_); complete_path(new_dir); mkdir(new_dir, S_IREAD | S_IWRITE | S_IEXEC); return 0;}FileSystem::parse_tildas(char *new_dir){ if(new_dir[0] == 0) return 1; /* new_dir is blank */ if(new_dir[0] == '~') { // first character is a tilda if(new_dir[1] == '/' || new_dir[1] == 0) { // user's home directory char string[256]; uid_t uid; struct passwd *pw; uid = getuid(); // get user id pw = getpwuid(uid); // get info for user sprintf(string, "%s%s", pw->pw_dir, &new_dir[1]); // print starting after tilda strcpy(new_dir, string); return 0; } else { // another user's home directory char string[256], new_user[256]; struct passwd *pw; int i, j; for(i = 1, j = 0; new_dir[i] != 0 && new_dir[i] != '/'; i++, j++) { // copy user name new_user[j] = new_dir[i]; } new_user[j] = 0; setpwent(); while(pw = getpwent()) { // get info for user if(!strcmp(pw->pw_name, new_user)) { // print starting after tilda sprintf(string, "%s%s", pw->pw_dir, &new_dir[i]); strcpy(new_dir, string); break; } } endpwent(); return 0; } }}FileSystem::parse_dots(char *new_dir){ if(new_dir[0] != '/') { // extend path completely char string[256]; if(!strlen(current_dir)) { // use pwd strcpy(string, new_dir); } else if(strcmp(current_dir, "/")) { // new_dir is not root if(current_dir[strlen(current_dir) - 1] == '/') sprintf(string, "%s%s", current_dir, new_dir); // current_dir already has ending / else sprintf(string, "%s/%s", current_dir, new_dir); // need ending / } else sprintf(string, "%s%s", current_dir, new_dir); strcpy(new_dir, string); }//printf("%s\n", new_dir); int changed = 1; while(changed) { // recursively remove ..s int i, j, len; len = strlen(new_dir); changed = 0; for(i = 0, j = 1; !changed && j < len; i++, j++) { if(new_dir[i] == '.' && new_dir[j] == '.') { changed = 1; while(new_dir[i] != '/' && i > 0) { // look for first / before .. i--; } if(i > 0) i--; // find / before this / while(new_dir[i] != '/' && i > 0) { // look for first / before first / before .. i--; }// i now equals /first filename before .. while(new_dir[j] != '/' && j < len) { // look for first / after .. j++; }// j now equals /first filename after .. while(j < len) { new_dir[i++] = new_dir[j++]; } new_dir[i] = 0; if((new_dir[0]) == 0) sprintf(new_dir, "/"); // root directory break; } } }//printf("%s\n", new_dir);}FileSystem::complete_path(char *filename){ if(!strlen(filename)) return 1;//printf("%s\n", filename); parse_tildas(filename);//printf("%s\n", filename); parse_dots(filename);//printf("%s\n", filename); // don't add end slash since this requires checking if dir}FileSystem::extract_dir(char *out, char *in){ strcpy(out, in); if(is_dir(in)) // complete string is not directory { complete_path(out); int i; for(i = strlen(out); i > 0 && out[i] != '/'; i--) { ; } if(i > 0) out[i] = 0; }}FileSystem::extract_name(char *out, char *in){ int i; if(!is_dir(in)) sprintf(out, ""); // complete string is directory else { for(i = strlen(in)-1; i > 0 && in[i] != '/'; i--) { ; } if(in[i] == '/') i++; strcpy(out, &in[i]); }}FileSystem::join_names(char *out, char *dir_in, char *name_in){ strcpy(out, dir_in); int len = strlen(out); int result = 0; while(!result) if(len == 0 || out[len] != 0) result = 1; else len--; if(len != 0) { if(out[len] != '/') strcat(out, "/"); } strcat(out, name_in);}long FileSystem::get_date(char *filename){ struct stat file_status; stat (filename, &file_status); return file_status.st_mtime;}FileSystem::change_dir(char *new_dir_){ char new_dir[256]; strcpy(new_dir, new_dir_); complete_path(new_dir);// cut ending slash if(strcmp(new_dir, "/") && new_dir[strlen(new_dir) - 1] == '/') new_dir[strlen(new_dir) - 1] = 0; update(new_dir); return 0;}FileSystem::add_end_slash(char *new_dir){ if(new_dir[strlen(new_dir) - 1] != '/') strcat(new_dir, "/");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -