int main (int argc, char * argv[]) { int force=0; char opt; extern int optind; while((opt = getopt(argc, argv, "f")) != -1) { //while options exist in commandline getopt switch(opt) { case 'f': force = 1; break; default: print_usage(); return -1; } } if (argc>optind+2) { int i; for(i=0;i<argc;++i) { fprintf(stderr,"%s ",argv[i]); } fprintf(stderr,"\nThis program takes only two command line arguments\n"); print_usage(); return -1; } if (argc==optind) { int i; for(i=0;i<argc;++i) { fprintf(stderr,"%s ",argv[i]); } fprintf(stderr,"\nNo arguments provided, this program takes two command line argument\n"); print_usage(); return -1; } char * src_file = argv[optind]; char * dst_file = argv[optind+1]; int cloned=0; cloned=clone_file(src_file,dst_file,force); //create a cloned file if (cloned==1) { int success=clone_file_params(src_file,dst_file); //clone original file parameters if (success==1)return 1; } return 0; }
static int cp(const char *src, const char *dst) { int pid; int ret = 0; if (use_clone) { struct stat sb; _cleanup_close_ int dest_desc = -1, source_desc = -1; if (lstat(src, &sb) != 0) goto normal_copy; if (S_ISLNK(sb.st_mode)) goto normal_copy; source_desc = open(src, O_RDONLY | O_CLOEXEC); if (source_desc < 0) goto normal_copy; dest_desc = open(dst, O_WRONLY | O_CREAT | O_EXCL | O_CLOEXEC, (sb.st_mode) & (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)); if (dest_desc < 0) { goto normal_copy; } ret = clone_file(dest_desc, source_desc); if (ret == 0) { struct timeval tv[2]; if (fchown(dest_desc, sb.st_uid, sb.st_gid) != 0) if(fchown(dest_desc, (__uid_t) - 1, sb.st_gid) != 0) log_error("Failed to chown %s: %m", dst); tv[0].tv_sec = sb.st_atime; tv[0].tv_usec = 0; tv[1].tv_sec = sb.st_mtime; tv[1].tv_usec = 0; futimes(dest_desc, tv); return ret; } close(dest_desc); dest_desc = -1; /* clone did not work, remove the file */ unlink(dst); /* do not try clone again */ use_clone = false; } normal_copy: pid = fork(); if (pid == 0) { execlp("cp", "cp", "--reflink=auto", "--sparse=auto", "--preserve=mode,timestamps", "-fL", src, dst, NULL); _exit(EXIT_FAILURE); } while (waitpid(pid, &ret, 0) < 0) { if (errno != EINTR) { ret = -1; log_error("Failed: cp --reflink=auto --sparse=auto --preserve=mode,timestamps -fL %s %s", src, dst); break; } } log_debug("cp ret = %d", ret); return ret; }
/** Write Variable **/ int write_variable(string path, string variable_name, string variable_value) { //path temp string path_tmp = path + "-tmp_file"; ///Clone File if (clone_file(path, path_tmp) == -1) return -1; //flag for controll if the variable has already been written bool flag_register = false; ofstream FILE; ifstream FILE_TMP; FILE.open(path.c_str(), std::ios::out); FILE_TMP.open(path_tmp.c_str(), std::ios::in); /* Read File */ bool end_file = false; while (end_file == false) { //get line string line = ""; getline(FILE_TMP, line); end_file = FILE_TMP.eof(); //check for comment if (line.compare(0,2,"//") == 0) { //copy line FILE << line; if (end_file == false) FILE << endl; continue; } //check for equal position std::size_t pos_equal; pos_equal = line.find('='); //if not found ignore line if (pos_equal == std::string::npos) { //copy line FILE << line; if (end_file == false) FILE << endl; continue; } //get variable name string tmp_name_var = line.substr (0, pos_equal); //remove blank characters in final of string while (tmp_name_var[tmp_name_var.length() - 1] == ' ') { tmp_name_var.resize(tmp_name_var.length() - 1); } ///check if the desired variable, if it is, overwrite the original file if (tmp_name_var == variable_name) { //registrar a variavel flag_register = true; FILE << tmp_name_var << " = " << variable_value; if (end_file == false) FILE << endl; } //else, copy line else { //copy line FILE << line; if (end_file == false) FILE << endl; continue; } }/* End read file */ ///if the variable is missing write a new line in final of file if (flag_register == false) FILE << endl << variable_name << " = " << variable_value; FILE.close(); FILE_TMP.close(); //delete temp file remove(path_tmp.c_str()); return 0; }
/** Write Comment **/ int write_comment(string path, int n_line, string comment) { ofstream FILE; ifstream FILE_TMP; ///if comment in last line if (n_line <= 0) { FILE.open(path.c_str(), std::ios::out | std::ios::app); //error if (FILE.is_open() == false) return -1; FILE << endl << comment; FILE.close(); return 0; } //path temp string path_tmp = path + "-tmp_file"; ///Clone File if (clone_file(path, path_tmp) == -1) return -1; FILE.open(path.c_str(), std::ios::out); FILE_TMP.open(path_tmp.c_str(), std::ios::in); /* Read File */ bool end_file = false; int current_line = 0; bool comment_exist = false; while (end_file == false) { //get line string line = ""; getline(FILE_TMP, line); end_file = FILE_TMP.eof(); current_line ++; //if comment already exists if (line == comment) comment_exist = true; if (current_line == n_line && comment_exist == false) { FILE << comment << endl; comment_exist = true; } //copy line FILE << line; if (end_file == false) FILE << endl; //check if line is more greater thant file if (end_file == true && comment_exist == false) FILE << endl << comment; }/* End read file */ FILE.close(); FILE_TMP.close(); if (comment_exist == true) return -2; return 0; }
int encode_file(char *filepath) { #ifdef DEBUG printf("processing %s\n", filepath); #endif // DEBUG if (!file_exists(filepath)) { fprintf(stderr, "Failed to decode file %s\n, file doesn't exitsts", filepath); return -1; } /** * Check if the file to be encoded is empty, if so, we don't need * to process it. */ struct stat filestat; if (-1 == stat(filepath, &filestat)) { perror(NULL); return -1; } if (0 == filestat.st_size) return 0; /** * If the file is not empty, we encode it and add a newline sign * when finish encoding the file */ char *input_path = clone_file(filepath); char *output_path = filepath; if (!file_exists(input_path) || !file_exists(output_path)) { fprintf(stderr, "Failed to make a clone of file %s\n", filepath); return -1; } int input_fd = open(input_path, O_RDONLY); int output_fd = open(output_path, O_WRONLY | O_TRUNC); if (-1 == input_fd || -1 == output_fd) { perror(NULL); return -1; } uint8_t read_buf[kNumRead], write_buf[kNumWrite]; int num_read, num_write; while (1) { memset(read_buf, 0, kNumRead); memset(write_buf, 0, kNumWrite); num_read = read(input_fd, read_buf, kNumRead); if (0 == num_read) break; // finish reading the file if (-1 == num_read) { fprintf(stderr, "Failed to read bytes from %s\n", input_path); return -1; } num_write = encode_block(read_buf, write_buf, num_read); if (num_write != write(output_fd, write_buf, num_write)) { fprintf(stderr, "Failed to write %d bytes into %s\n", num_write, output_path); return -1; } } /** * write a newline sign to the output_fd */ write_buf[0] = 0x0a; if (1 != write(output_fd, write_buf, 1)) { fprintf(stderr, "Failed to write the newline sign to %s\n", output_path); return -1; } /** * close everything, remove the file_clone */ close(input_fd); close(output_fd); if (-1 == unlink(input_path)) { fprintf(stderr, "Failed to remove file %s\n", input_path); return -1; } return 0; }