how would you be able to check if the files have the same/different i-node numbers in C?
Because I want the rightly get the source and destination file information, where the files need to be rightly tested if they are the same.
Code:
#define BUFFER 100 // ** increased - file path can get pretty long
#define buffersize 4096
#define copymode 0644
void error(char *, char *);
int file_exist(char *filename)
{
struct stat buffer;
return (stat (filename, &buffer) == 0);
}
int main()
{
int ac;
char *avc[4096];
int in_fd, out_fd, chars_n;
char buf[BUFFERSIZE];
char ch, sourceFile[20], targetFile[20];
FILE *source, *target;
printf("Enter name of file to copy\n");
fgets(source_file, 20, stdin);
source = fopen(sourceFile, "r");
*avc = sourceFile;
if( source == NULL )
{
printf("Press any key to exit...\n");
exit(1);
}
printf("Enter name of target file\n");
fgets(targetFile, 20, stdin);
// open(path, O_WRONLY | O_CREAT | O_TRUNC, mod);
if (file_exist (targetFile))
{
printf("File exists. \n");
}
else
target = fopen(targetFile, "w");
int dFN;
dFN = malloc(strlen(targetFile) + strlen(av[2] + 1));
if( target == NULL )
{
fclose(source);
printf("Press any key to exit...\n");
exit(1);
}
while( ( ch = fgetc(source) ) != EOF )
fputc(ch, target);
printf("File copied successfully.\n");
fclose(source);
fclose(target);
if ( ac != 3 ){
fprintf( stderr, "usage: %s source destination\n", *avc);
exit(1);
}
if ( (in_fd=open(avc[1], O_RDONLY)) == -1 )
error("Cannot open ", avc[1]);
if ( (out_fd=creat( avc[2], copymode)) == -1 )
error( "Cannot creat", avc[2]);
while ( (chars_n = read(in_fd , buf, buffersize)) > 0 )
if ( write( out_fd, buf, chars_n ) != chars_n )
error("Write error to ", av[2]);
if ( chars_n == -1 )
error("Read error from ", avc[1]);
if ( close(in_fd) == -1 || close(out_fd) == -1 )
error("Error closing files","");
return 0;
}
void error(char *s1, char *s2)
{
fprintf(stderr,"Error: %s ", s1);
perror(s2);
exit(1);
}
Use the stat(2) or fstat function call, which returns various informations about a file, including its inode number.
See for example http://pubs.opengroup.org/onlinepubs/009695399/functions/stat.html
Related
when I input "./test test.c /home/user1/Desktop/" it doesnt work anything.
I want to make copy file from (now_path) to (other_path).
But, I dont know why it does not work I think it is perfect code. Is it has error or need some more other codes??
char ch;
int src, dst;
if( argc != 3 )
{
printf("argument error\n");
printf("usage: ./a.out src dest\n");
}
src = open( argv[1], O_RDONLY );
dst = open( argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644 );
while( read( src, &ch, 1 ))
write( dst, &ch, 1 );
close( src );
close( dst );
return 0;
It's impossible to figure out unless you start to check return values. The open function returns a negative value on failure, and errno is set to indicate what went wrong.
Same goes for read and write. They returns the number of bytes read/written and a negative value on failure. errno is also set by these functions.
You could use constructs like this:
if ((src = open( argv[1], O_RDONLY )) < 0) {
fprintf(stderr, "Error accessing source file.\n");
fprintf(stderr, "errno: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
Your code is ok but you might want to ensure that the source file is readable before trying to copy it's content. Also you may want to terminate the program if an error occurs.
char ch;
int src, dst;
if( argc != 3 )
{
printf("argument error\n");
printf("usage: ./a.out src dest\n");
exit(1); // Terminate the program
}
if ((src = open( argv[1], O_RDONLY )) == -1)
{
printf("Error accessing source file.\n");
exit(1);
}
if (dst = open( argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644 )) == -1)
{
printf("Error accessing destination file.\n");
exit(1);
}
while( read( src, &ch, 1 ) > 0 )
write( dst, &ch, 1 );
close( src );
close( dst );
return 0;
Also, if the second argument will always be a directory, you'll need to set the open command for the destination file to the combination of the second and first arguments (argv[2] joined with argv[1]).
For this you can use the strcat function which copies the content of the second string into the first. Start by adding #include <string.h> to the header of your program:
char* buffer[BUF_SIZE];
int src, dst;
int bytesRead;
char dstFile[1024];
if (argc != 3)
{
printf("argument error\n");
printf("usage: ./a.out src dest\n");
}
if ((src = open(argv[1], O_RDONLY)) == -1)
{
printf("Error accessing source file.\n");
exit(1);
}
strcat(dstFile, argv[2]);
strcat(dstFile, argv[1]);
if ((dst = open(dstFile, O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1)
{
printf("Error accessing destination file. %s\n", dstFile);
exit(1);
}
while ((bytesRead = read(src, buffer, BUF_SIZE)) > 0)
{
write(dst, buffer, bytesRead);
}
close(src);
close(dst);
return 0;
I want to have a successful copy file program, where I can have the result: ./a.out 1.c examples3/16.c to be successful, where I can successfully make a new directory for my copied file. How can you do this, because I get errors trying to do it. I can copy the 1.c file successfully in one place, and I can copy the file into an existing directory but not successful in copying the file into a newly made directory. How can you do this and fix this problem?
code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#define BUFFERSIZE 4096
#define COPYMODE 0644
int file_exist (char *filename)
{
struct stat buffer;
return (stat (filename, &buffer) == 0);
}
int main(int ac, char *av[])
{
int ch; //ch - character no.
struct stat sb;
char directory[120];
FILE *source, *target;
/* from http://stackoverflow.com/questions/30215462/how-to-get-the-source-files-the-file-which-i-want-to-copy-and-the-copied-file/30217023#30217023 */
if (ac <= 2) {
printf("Enter source and destination file names\n");
exit(EXIT_FAILURE);
}
if ( strcmp(av[1], av[2]) ==0 )
{
printf("the files are the same\n");
exit(1);
}
if (file_exist (av[2]))
{
printf ("the destination file exists\n");
exit(1);
}
//printf("which directory do you want to send your destination file?");
//scanf("%s", directory);
char serv_name[1000];
mkdir("newdir/", S_IRWXU | S_IRWXG | S_IRWXO);
snprintf(serv_name, sizeof(serv_name), "newdir/%s", av[2]);
FILE* f = fopen(serv_name, "w");
if (f < 0) {
perror("CLIENT:\n");
exit(1);
}
source = fopen(av[1], "r");//getting and opening source file
if( source == NULL ) {
printf("Press any key to exit...\n");
exit(EXIT_FAILURE);
}
target = fopen(av[2], "w");//getting and opening destination file
if( target == NULL ) {
fclose(source);
printf("Press any key to exit...\n");
exit(EXIT_FAILURE);
}
while( ( ch = fgetc(source) ) != EOF )
fputc(ch, target);
fclose(source);
fclose(target);
printf("File copied successfully.\n");
/* from http://stackoverflow.com/questions/30215462/how-to-get-the-source-files-the-file-which-i-want-to-copy-and-the-copied-file/30217023#30217023 */
if (stat(av[1], &sb) == -1) {
perror("stat");
exit(1); //exit(EXIT_SUCCESS);
}
else
if (chmod(av[2], sb.st_mode & 07777))//http://stackoverflow.com/questions/18032574/how-can-i-copy-permissions-from-a-file-that-already-exists
{
perror("chmod");
}
printf("Source File: %s, Inode number: %d, Mode: 0x%04X\n", av[1], (unsigned)sb.st_ino, (unsigned)sb.st_mode);
if (stat(av[2], &sb) == -1) {
perror("stat");
exit(1);
}
char *str;
str = (char *) malloc(15);
strcpy(str, av[2]);
if (stat(av[2], &sb) == -1) {//http://stackoverflow.com/questions/7430248/creating-a-new-directory-in-c
mkdir(av[2], 0700);
}
printf("Destination File: %s, inode number: %d, Address = %u, Mode: 0x%04X\n", av[2], (unsigned)sb.st_ino, str, (unsigned)sb.st_mode);
free(str);
return 0;
}
I can successfully make a new directory for my copied file. [...] but not successful in copying the file into a new directory or different
The problem may come from the directory creation:
If you call you program with: ./a.out foo bar
snprintf(serv_name, sizeof(serv_name), "newdir/%s", av[2]);
FILE* f = fopen(serv_name, "w");
Your program will try to open newdir/bar: OK
If you call you program with: ./a.out foo /path/to/bar
snprintf(serv_name, sizeof(serv_name), "newdir/%s", av[2]);
FILE* f = fopen(serv_name, "w");
Your program will try to open newdir//path/to/bar: That will certainly fail.
So your problem comes from:
snprintf(serv_name, sizeof(serv_name), "newdir/%s", av[2]);
FILE* f = fopen(serv_name, "w");
if (f < 0) {
perror("CLIENT:\n");
exit(1);
}
You cannot open f if the tree directory is not correct.
I want to get the source file information, when I want to copy the source file and then get the destination file information, when the source file has already being copied. The problem with the code is that I can't copy and get the source and destination file information.
How could you be able to fix my code to copy a file and get source and destination information?
Code:
#define BUFFER 100 // ** increased - file path can get pretty long
#define BUFFERSIZE 4096
#define COPYMODE 0644
void oops(char *, char *);
int file_exist(char *filename)
{
struct stat buffer;
return (stat (filename, &buffer) == 0);
}
int main(int argc, char *argv[])
{
char ch, source_file[20], target_file[20];
FILE *source, *target;
// printf("Enter name of file to copy\n");
// fgets(source_file, 20, stdin);
source_file = argv[20];
source = fopen(source_file, "r");
if( source == NULL )
{
printf("Press any key to exit...\n");
exit(EXIT_FAILURE);
}
printf("Enter name of target file\n");
fgets(target_file, 20 , stdin);
target = fopen(target_file, "w");
if( target == NULL )
{
fclose(source);
printf("Press any key to exit...\n");
exit(EXIT_FAILURE);
}
while( ( ch = fgetc(source) ) != EOF )
fputc(ch, target);
printf("File copied successfully.\n");
fclose(source);
fclose(target);
struct stat sb;
if (argc != 2) {
fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (stat(argv[1], &sb) == -1) {
perror("stat");
exit(EXIT_SUCCESS);
}
printf("File type: ");
switch (sb.st_mode & S_IFMT) {
case S_IFBLK: printf("block device\n"); break;
case S_IFCHR: printf("character device\n"); break;
case S_IFDIR: printf("directory\n"); break;
case S_IFIFO: printf("FIFO/pipe\n"); break;
case S_IFLNK: printf("symlink\n"); break;
case S_IFREG: printf("regular file\n"); break;
case S_IFSOCK: printf("socket\n"); break;
default: printf("unknown?\n"); break;
}
printf("I-node number: %ld\n", (long) sb.st_ino);
exit(EXIT_SUCCESS);
}
void oops(char *s1, char *s2)
{
fprintf(stderr,"Error: %s ", s1);
perror(s2);
exit(1);
}
I am unsure where your difficulty lies, apart from errors mentioned in comment. I've simplified your code, removing the bitfield masks as I don't have their definitions.
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char *argv[])
{
int ch; // <--- int not char
struct stat sb;
FILE *source, *target;
if (argc < 3) {
printf("Enter two args: source and destination file names\n");
exit(EXIT_FAILURE);
}
source = fopen(argv[1], "r");
if( source == NULL ) {
printf("Press any key to exit...\n");
exit(EXIT_FAILURE);
}
target = fopen(argv[2], "w");
if( target == NULL ) {
fclose(source);
printf("Press any key to exit...\n");
exit(EXIT_FAILURE);
}
while( ( ch = fgetc(source) ) != EOF )
fputc(ch, target);
fclose(source);
fclose(target);
printf("File copied successfully.\n");
if (stat(argv[1], &sb) == -1) {
perror("stat");
exit(EXIT_SUCCESS);
}
printf("File %s type: 0x%04X Mode: 0x%04X\n", argv[1], (unsigned)sb.st_ino, (unsigned)sb.st_mode);
if (stat(argv[2], &sb) == -1) {
perror("stat");
exit(EXIT_SUCCESS);
}
printf("File %s type: 0x%04X Mode: 0x%04X\n", argv[2], (unsigned)sb.st_ino, (unsigned)sb.st_mode);
return 0;
}
Program output:
>test test.c test2.c
File copied successfully.
File test.c type: 0x0000 Mode: 0x81B6
File test2.c type: 0x0000 Mode: 0x81B6
I get an error when I try to make the Makefile on the following C program.
int main()
{
char filename_src[101], filename_dest[101];
printf("\nSource file: ");
gets_s(filename_src, 100);
printf("\nDestination filename: ");
gets_s(filename_dest, 100);
if(copy_file(filename_src, filename_dest) == 0)
printf("Copy Successful\n");
else
fprintf(stderr, "Error during copy!");
copyfile( filename_src, filename_dest );
}
int copyfile( const char *test1, const char *test2 )
{
int infile, outfile;
ssize_t nread;
char buffer[BUFSIZE];
if( ( infile = open(test1, O_RDONLY) ) == -1 )
return (-1);
if( ( outfile = open(test2,O_WRONLY|O_CREAT|O_TRUNC,PERM ) == -1)
{
close(infile);
return (-2);
}
/* now read from test1 BUFSIZE chars at a time*/
while( (nread = read(infile, buffer, BUFSIZE) ) > 0)
{
/*write buffer to output file*/
if( write(outfile, buffer, nread) < nread )
{
close(infile);
close(outfile);
return (-3); /*write error*/
}
}
close(infile);
close(outfile);
if( nread == -1 )
return (-4); /*error on last read*/
else
return (0); /*all is well */
}
This is my C program. I get the error "expected ‘)’ before ‘{’ token" when I try to make the Makefile on terminal. Can anyone tell me where the problem in my code is?
Thank you
if ( ( outfile = open(test2,O_WRONLY|O_CREAT|O_TRUNC,PERM ) == -1)
^ 2 1 1 2
As you can see this parenthesis is unmatched.
I am brand new to System Programming and am having some trouble learning how directories and files work. The program should take two arguments(directories), if both are existing directories then just copy the files from the first argument into the second. If the second is a file, return with an error, finally if the second argument doesn't exist, then create it and copy the files over.
The problem occurs when I am trying to open each file to copy over the contents to the new created copy. I can get the list of all files in the first directory. If I remove copy the data(aka. in_fd) the program copies all the files over, they just are empty files.
So far the program checks the input, makes the directory if needed. All that is left is to copy over the files.
Any help will be appreciated. I saw this on other questions but none of the answers seemed to help. Thank you in advance for all your help.
#define BUFFERSIZE 4096
#define COPYMODE 0644
void oops(char *, char *);
int main(int ac, char *av[])
{
int in_fd, out_fd, n_chars;
char buf[BUFFERSIZE];
/* check args */
if ( ac != 3 ){
fprintf( stderr, "usage: %s source destination\n", *av);
exit(1);
}
//Directory pointers
DIR *sender_dir_ptr;
DIR *receiver_dir_ptr;
struct dirent *direntp;
//Used to test second argument for new/existing directory
struct stat info;
if(lstat(av[2],&info) != 0) {
if(errno == ENOENT) {
//doesn't exist, make directory
mkdir(av[2], 0700);
if ((receiver_dir_ptr = opendir(av[2])) == NULL )
oops("cannot open %s\n", av[2]);
} else if(errno == EACCES) {
// we don't have permission to know if
// the path/file exists.. impossible to tell
oops("Permission Denied", av[2]);
}
}
//so, it exists.
if(S_ISDIR(info.st_mode)) {
//it's a directory. Assign the directory pointer
if ((receiver_dir_ptr = opendir(av[2])) == NULL )
oops("cannot open %s\n", av[2]);
} else if(S_ISREG(info.st_mode)) {
//it's a file, display error and exit
oops("File exists but looking for a directory", av[2]);
}
if ((sender_dir_ptr = opendir(av[1])) == NULL )
oops("cannot open %s\n", av[1]);
else
{
struct stat st_buf;
//Go through sender directory and copy over all files to new directory
while (( direntp = readdir(sender_dir_ptr)) != NULL )
{
lstat(direntp->d_name, &st_buf);
if (S_ISDIR (st_buf.st_mode))
{
continue;
}
else if (S_ISREG (st_buf.st_mode))
{
printf("direntp= %s\n",direntp->d_name);
char tmp_in[strlen(av[1])];
strcpy(tmp_in, av[1]);
strcat(tmp_in, "/");
strcat(tmp_in, direntp->d_name);
if ((in_fd=open(tmp_in, O_RDONLY)) == -1 )
oops("Cannot open,", direntp->d_name);
//Create pathname to the second directory
char* filename = av[2];
char tmp[strlen(av[2])];
strcpy(tmp, av[2]);
strcat(tmp, "/");
strcat(tmp, direntp->d_name);
printf("filename: %s \n", tmp);
//Create new file
if ((out_fd=creat(tmp, COPYMODE)) == -1 )
oops( "Cannot creat", tmp);
//Write old file data into the new files
while ( (n_chars = read(in_fd , buf, BUFFERSIZE)) > 0 )
if ( write(out_fd, buf, n_chars ) != n_chars )
oops("Write error to ", av[2]);
if ( n_chars == -1 )
oops("Read error from ", av[1]);
//close files
if ( close(in_fd) == -1 || close(out_fd) == -1 )
oops("Error closing files","");
}
else{
printf("File: %s \n",direntp->d_name);
}
}
//Close directories
closedir(sender_dir_ptr);
closedir(receiver_dir_ptr);
}
return 0;
}
void oops(char *s1, char *s2)
{
fprintf(stderr,"Error: %s ", s1);
perror(s2);
exit(1);
}
'direntp->d_name' is filename only, not a complete file specification as required by open() etc. You need to strcat the name to the folder path.