New bug: multiple files

This commit is contained in:
Sergiusz Warga 2021-03-09 23:20:28 +01:00
parent 9a6d1dfbea
commit 53de348216
3 changed files with 71 additions and 17 deletions

View File

@ -8,15 +8,15 @@ I'm sure you are all proficient C/C++ programmers, but - just in case you had a
Write your own version of Unix "cp" (copy) command.
As a bare minimum - please write a program that:
- accepts source and destination filenames as its arguments (you DO remember how to use argc and argv ?)
- makes a copy of indicated file
- returns 0 on success, any non-zero value on error
- uses ONLY POSIX I/O functions (open, close, read, write - consult appropriate manuals)
- [x] accepts source and destination filenames as its arguments (you DO remember how to use argc and argv ?)
- [x] makes a copy of indicated file
- [x] returns 0 on success, any non-zero value on error
- [x] uses ONLY POSIX I/O functions (open, close, read, write - consult appropriate manuals)
NOTICE: Do not assume, that you can read entire file into memory. Please read manuals carefully - pay attention to each function's return value!
I'm sure this task will prove to be to easy to some of you - in this case you can extend your program - for example you can add features to allow:
- copy source_file dest_dir (copy source file to the indicated directory, keeping its name)
- [ ] copy source_file dest_dir (copy source file to the indicated directory, keeping its name)
- copy file1 file2 file3 dest_dir (copy files file1...file3 into destination directory)
- ... ?

View File

@ -1,13 +1,18 @@
// UNIX cp copy
// Wrote for Computer Networks and Systems lab classes
// AUTHOR : Sergiusz Warga
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <string.h>
#define BUFFER_SIZE 8
#define BUFFER_SIZE 8 // TODO: Think about it.
enum ERROR{NO_ARGUMENTS, WRONG_ARGUMENT};
enum ERROR{NO_ARGUMENTS, WRONG_ARGUMENT, DUNNO};
int print_error_message(enum ERROR error_type) {
if (error_type == NO_ARGUMENTS) {
@ -17,6 +22,8 @@ int print_error_message(enum ERROR error_type) {
} else if (error_type == WRONG_ARGUMENT) {
fprintf(stderr, "cp: unrecognized option\n");
fprintf(stderr,"Try cp --help for more information.\n");
} else if (error_type == DUNNO) {
fprintf(stderr, "Something went wrong!\n");
}
return 0;
}
@ -26,10 +33,28 @@ int print_help() {
return 0;
}
int cp(char *argv[]){
int is_dir(const char *name) {
struct stat path;
stat(name, &path);
return S_ISDIR(path.st_mode);
}
int cp(char *old_name, char *new_name) {
// int cp(char *old_argv, char *new_argv) {
// char *old_name, *new_name;
// strncpy(old_name, old_argv, sizeof(old_argv));
// strncpy(new_name, new_argv, sizeof(new_argv));
int old, new;
old = open(argv[1], O_RDONLY);
new = open(argv[2], O_CREAT | O_WRONLY);
if (is_dir(new_name)) {
printf("%s\n", new_name);
strncat(new_name, "/", 1);
printf("%s\n", new_name);
strncat(new_name, old_name, sizeof(old_name));
printf("%s\n", new_name);
}
printf("Moving %s to %s\n", old_name, new_name);
old = open(old_name, O_RDONLY);
new = open(new_name, O_CREAT | O_WRONLY);
char buffer[BUFFER_SIZE];
int read_bytes;
@ -37,10 +62,7 @@ int cp(char *argv[]){
write(new, buffer, read_bytes);
}
struct stat mod_bits;
stat(argv[1], &mod_bits);
chmod(argv[2], mod_bits.st_mode);
printf("%s moved to %s\n", old_name, new_name);
close(old);
close(new);
@ -48,6 +70,15 @@ int cp(char *argv[]){
return 0;
}
int copy_mod_bits(char *old_name, char *new_name) {
struct stat mod_bits;
stat(old_name, &mod_bits);
chmod(new_name, mod_bits.st_mode);
return 0;
}
int main(int argc, char *argv[]) {
if (argc == 1) {
print_error_message(NO_ARGUMENTS);
@ -63,7 +94,17 @@ int main(int argc, char *argv[]) {
}
}
if (argc == 3) {
if (cp(argv) > 0) return 1;
if (cp(argv[1], argv[2]) > 0) return 1;
copy_mod_bits(argv[1], argv[2]);
}
if (argc > 3) {
int no_of_old_files = argc - 2;
for (int i = 1; i <= no_of_old_files; ++i) {
printf("TOOO %s\n", argv[argc-1]);
if (cp(argv[i], argv[argc-1]) > 0) return 1;
copy_mod_bits(argv[i], argv[argc-1]);
}
}
return 0;
}

View File

@ -1,7 +1,20 @@
#!/bin/bash
# Clean and compile
rm -f old_file new_file;
echo "QWERTYUIOP" > old_file;
echo "ASDFGHJKLZ" > old_file2;
mkdir new_dir;
gcc -Wall main.c -o cp;
# Run
./cp old_file new_file;
chmod +rw new_file;
diff old_file new_file;
./cp old_file old_file2 new_dir;
tree;
# Check if everything went well
if diff old_file new_file; diff old_file new_dir/old_file; diff old_file2 new_dir/old_file2; then
echo "Well done!"
else
echo "Something went wrong!"
fi
# Clean
rm -f old_file new_file new_dir/old_file new_dir/old_file2;
rmdir new_dir;