making a new directory for my copied file in C - c

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.

Related

Creation archive problem using libzip and C

Im trying to create program for building archives using libzip and C. Function below must create archive from files. Name of directory with files and name of output file passed as a command line arguments. Code works without any errors. The main problem that program does not create a .zip file, and I don`t understend why.
#include <zip.h>
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <stdbool.h>
#include <string.h>
static bool is_modified (char *filename);
static void create_zip (char *source_name, char *output_filename, char *dir_name)
{
int err = 0;
DIR *dir = opendir(dir_name);//open directory
struct dirent *entry;
if(!dir){
fprintf(stderr, "Cannot read directory\n");
exit(1);
}
fprintf(stdout, "DIR - [%s]\n", dir_name);
zip_t *archive_zip = zip_open(output_filename, ZIP_CREATE, &err);//create zip
if(archive_zip == NULL)
{
zip_error_t ziperr;
zip_error_init_with_code(&ziperr, err);
fprintf(stderr, "Failed to create archive, error -[%i]\n", err);
zip_close(archive_zip);
exit(1);
}else
printf("Archive [%s] created\n", output_filename);
while((entry = readdir(dir)) != NULL)// walking through directory
{
if(strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0 && strcmp(entry->d_name, source_name) !=0)
{
zip_source_t *source = zip_source_file(archive_zip, entry->d_name, 0, 0);//creating source for every file in dir
if(source == NULL)
{
fprintf(stderr, "Cant create source file [%s]\n", entry->d_name);
}
if(zip_file_add(archive_zip, entry->d_name, source, ZIP_FL_OVERWRITE) < 0)// adding it to archive with overwrite flag
{
zip_source_free(source);
fprintf(stderr, "Cant add file [%s]\n", entry->d_name);
}else
fprintf(stderr, "File [%s] added\n", entry->d_name);
}
}
zip_close(archive_zip);
closedir(dir);
}
int main(int argc, char **argv)
{
if (argc != 3) {
fprintf(stderr, "Usage: %s <output_file> <input_dir_name>\n", argv[0]);
return 1;
}
create_zip(argv[0],argv[1], argv[2]);
return 0;
}
Output looks like
DIR - [test_dir]
Archive [test] created
File [f1.txt] added
File [f2.txt] added
Thank you for help).

fopen: file does not exist but it does

I want to read all files that I can find in the folder where my executable is, except the runnable file that I'm running. I code the following code but, although this list correctly the files that I have in my folder, I cannot open them with fopen because fopen prints that the file doesn't exists. If I do gedit "path of the file obtained from my program in c" then it opens perfectly from the term. Where is the bug?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
int main (int argc, char **argv) {
//Determining the number of files we have.
//We call to a bash command http://stackoverflow.com/questions/646241/c-run-a-system-command-and-get-output
FILE *fp, *fin;
char path[1035], cwd[1024];
int scanned = 0;
/* Open the command for reading. */
//https://askubuntu.com/questions/370697/how-to-count-number-of-files-in-a-directory-but-not-recursively
//This count soft and hard links also (I think)
fp = popen("ls -F |grep -v /", "r");
if (fp == NULL) {
printf("Failed to run command\n" );
exit(1);
}
/* Read the output a line at a time - output it. */
//Loop for each file. Be careful! if the exe is inside, it will also be counted!
while (fgets(path, sizeof(path)-1, fp) != NULL) {
printf("Reading file: %s\n", path);
fin=fopen(path,"r");
scanned = 0;
printf("caa");
if (fin != NULL){
printf("AA\n");
fclose(fin);
}
if (!fin)perror("fopen");
printf("Done! \n");
}
/* close */
pclose(fp);
printf("end");
return 0;
}
There are 2 bugs in your code:
when the code updates the "path" variable in your code. It has a newline at the end which needs to be corrected to NUL. This gives an incorrect path.
Something like below can be appended to your code:
while (fgets(path, sizeof(path)-1, fp) != NULL) {
len=strlen(path);
path[len-1]='\0';
Use 'ls -A1', since 'ls -F' adds a '*' in binary name:
fp = popen("ls -A1 |grep -v /", "r");
ok so just in case someone else needs a better approach, I redid the code with the comments I had. Here I let you the new code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
int isDirectory(const char *path) {
struct stat statbuf;
if (stat(path, &statbuf) != 0)
return 0;
return S_ISDIR(statbuf.st_mode);
}
int main (int argc, char **argv) {
FILE *fp, *fin;
char path[1035], cwd[1024];
int scanned = 0;
int ints;
DIR *dir;
struct dirent *ent;
//getcwd prints directory where the app ran.
if ((dir = opendir (getcwd(cwd, sizeof(cwd)))) != NULL) {
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL) {
/*Skips . and ..*/
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) continue;
if (isDirectory(ent->d_name) != 0) continue;
printf ("Reading file: %s\n", ent->d_name);
scanned = 0;
fin=fopen(ent->d_name,"r");
if (fin != NULL){
while ((scanned = fscanf(fin, "%d", ints)) != EOF) {
if(scanned == 1){
printf("%d\n", ints);
}else {
printf("Whoops! Input format is incorrect!\n");
break;
}
} //LOOP: reading file
fclose(fin);
}
if (!fin)perror("fopen");
printf("Done! \n");
}//LOOP: while opendir
closedir (dir);
} else {
/* could not open directory */
perror ("opendir");
return EXIT_FAILURE;
}
return 0;
}

Opening a file using relative path

The following code is supposed to work as follows: print the list of the files in a directory, and print the content of each .c file.
it works fine when executed in UNIX for the same directory: ./a.out ./
However, I was not able to make it work for ./a.out ../differentDir execution.
I know that if the absolute path is provided as an argument, I could use argv[1] for that. However, when it is provided in a form of a relative path I am lost.
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUFFSIZE 32768
int main(int argc, char **argv) {
char buf[BUFFSIZE];
DIR *dp;
struct dirent *dirp;
char filename[80];
int name_length;
FILE *fp;
if (argc != 2) {
fprintf(stderr, "usage: %s dir_name\n", argv[0]);
exit(1);
}
if ((dp = opendir(argv[1])) == NULL ) {
fprintf(stderr, "can't open '%s'\n", argv[1]);
exit(1);
}
while ((dirp = readdir(dp)) != NULL ){
printf("%s\n", dirp->d_name);
memset(filename, '\0', sizeof(filename));
strcpy(filename, dirp->d_name);
printf(" ** %s ", filename);
name_length = strlen(filename);
printf(" name_length=%d \n", name_length);
if (findC(filename)) // checking if the file has a .c extension
{
fp=fopen(filename, "r");
if (fp == NULL)
fprintf(stderr, "Can't open .C file!\n");
else
{// if the file was opened successfuly:
do
{
fgets(buf,BUFFSIZE,fp); // reading each line until buffer is full or until reaching whitespace
buf[strlen(buf)-1]='\0'; // removing the trailing whitespace from the buffer
puts(buf);
}
while (!feof(fp));
printf("\n\n");
fclose(fp);
}
}
}
closedir(dp);
return(0);
}
/*FindC method gets a c-string that represents a file name; returns 1 if the file ends with .C extension, else returns 0*/
int findC(char * name)
{
int len = strlen(name);
if (len>=2 && name[len-2]=='.' && tolower(name[len-1])=='c')
return 1;
return 0;
}
Upon opening the file to read, the file pathname needs to also be relative.
// Form prefix for complete relative file name
char filename[MAXPATH];
strcpy(filename, argv[1]);
// append '/' if directory path does not end in '/'
if (TBD_code(filename)) {
strcat(filename, "/");
}
char *end = filename[strlen(filename)];
while ((dirp = readdir(dp)) != NULL ){
printf("%s\n", dirp->d_name);
if (findC(dirp->d_name)) {
// append filename to prefix
strcpy(end, dirp->d_name);
fp=fopen(filename, "r");
...
You can use realpath(argv1...) like in this example. realpath will return the absolute path for a relative path.
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
int main(int argc, char **argv) {
char *path = "../..";
char buff[PATH_MAX + 1]; /* not sure about the "+ 1" */
char *res = realpath(path, buff);
if (res) {
printf("This source is at %s.\n", buff);
} else {
perror("realpath");
exit(EXIT_FAILURE);
}
return 0;
}
To include the desired behavior in your program, you can use realpathin your code:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <ctype.h>
#include <dirent.h>
#include <string.h>
#define BUFFSIZE 32768
int main(int argc, char **argv) {
char buf[BUFFSIZE];
DIR *dp;
struct dirent *dirp;
char filename[80];
int name_length;
FILE *fp;
char buff[PATH_MAX + 1]; /* not sure about the "+ 1" */
if (argc != 2) {
fprintf(stderr, "usage: %s dir_name\n", argv[0]);
exit(1);
}
char *res = realpath(argv[1], buff);
if ((dp = opendir(res)) == NULL ) {
fprintf(stderr, "can't open '%s'\n", argv[1]);
exit(1);
}
while ((dirp = readdir(dp)) != NULL ){
printf("%s\n", dirp->d_name);
memset(filename, '\0', sizeof(filename));
strcpy(filename, dirp->d_name);
printf(" ** %s ", filename);
name_length = strlen(filename);
printf(" name_length=%d \n", name_length);
if (findC(filename)) // checking if the file has a .c extension
{
fp=fopen(filename, "r");
if (fp == NULL)
fprintf(stderr, "Can't open .C file!\n");
else
{// if the file was opened successfuly:
do
{
fgets(buf,BUFFSIZE,fp); // reading each line until buffer is full or until reaching whitespace
buf[strlen(buf)-1]='\0'; // removing the trailing whitespace from the buffer
puts(buf);
}
while (!feof(fp));
printf("\n\n");
fclose(fp);
}
}
}
closedir(dp);
return(0);
}
/*FindC method gets a c-string that represents a file name; returns 1 if the file ends with .C extension, else returns 0*/
int findC(char * name)
{
int len = strlen(name);
if (len>=2 && name[len-2]=='.' && tolower(name[len-1])=='c')
return 1;
return 0;
}
You could first change to the directory chdir either with relative or absolute path and the get the absolute path via the getcwd
#include <sys/types.h>
#include <string.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define BUFFSIZE 32768
#define PATH_SIZE 512
int main(int argc, char **argv) {
char buf[BUFFSIZE];
char path[PATH_SIZE];
DIR *dp;
struct dirent *dirp;
char filename[80];
int name_length, r;
FILE *fp;
if (argc != 2) {
fprintf(stderr, "usage: %s dir_name\n", argv[0]);
exit(1);
}
strcpy(path, argv[1]);
r = chdir(path);
if( r != 0 )
{
printf("Invalid path '%s'\n",path);
exit(1);
}
getcwd(path,PATH_SIZE);
if ((dp = opendir(path)) == NULL ) {
fprintf(stderr, "can't open '%s'\n", argv[1]);
exit(1);
}
while ((dirp = readdir(dp)) != NULL ){
printf("%s\n", dirp->d_name);
memset(filename, '\0', sizeof(filename));
strcpy(filename, dirp->d_name);
printf(" ** %s ", filename);
name_length = strlen(filename);
printf(" name_length=%d \n", name_length);
if (findC(filename)) // checking if the file has a .c extension
{
fp=fopen(filename, "r");
if (fp == NULL)
fprintf(stderr, "Can't open .C file!\n");
else
{// if the file was opened successfuly:
do
{
fgets(buf,BUFFSIZE,fp); // reading each line until buffer is full or until reaching whitespace
buf[strlen(buf)-1]='\0'; // removing the trailing whitespace from the buffer
puts(buf);
}
while (!feof(fp));
printf("\n\n");
fclose(fp);
}
}
}
closedir(dp);
return(0);
}
/*FindC method gets a c-string that represents a file name; returns 1 if the file ends with .C extension, else returns 0*/
int findC(char * name)
{
int len = strlen(name);
if (len>=2 && name[len-2]=='.' && tolower(name[len-1])=='c')
return 1;
return 0;
}

Why do I get the following linkage error "undefined reference to `__printf__'"

I am using JaetBrains' Clion with MinGW 3.2.1 on windows. and I'm trying to build a project in c.
I keep getting the following linkage error:
undefined reference to `printf'
any Idea How to solve it?
this is my code:
#include <fcntl.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h> // for time measurement
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <libintl.h>
#define BUFFERSIZE 1
int main(int argc, char** argv) {
assert(argc == 3);
char* inputDirPath = argv[0];
char* keyFilePath = argv[1];
char* outputDirPath = argv[2];
// open key file
int key_fd = open(keyFilePath, O_RDONLY);
if (key_fd < 0) {
printf("Failed opening Key file %s. Error: %s\n", keyFilePath, strerror(errno));
return errno;
}
// making sure the file is not empty
char keyFirstChar;
if (read(key_fd, (void*)keyFirstChar, 1) == 0)
{
printf("Error. Key file is empty %s.", keyFilePath);
return errno;
}
else {
// go back to the begining of the file.
assert(!close(key_fd));
key_fd = open(keyFilePath, O_RDONLY);
if (key_fd < 0) {
printf("Failed opening Key file %s. Error: %s\n", keyFilePath,
strerror(errno)
);
return errno;
}
}
// Temp file name
char inputFilepath[200] ;
struct dirent *dirEntity;
DIR *inputDir_dfd;
// open directory stream
assert((inputDir_dfd = opendir(inputDirPath)) != NULL);
while ((dirEntity = readdir(inputDir_dfd)) != NULL)
{
// full path to input file
sprintf(inputFilepath, "%s/%s",inputDirPath, dirEntity->d_name) ;
// call stat to get file metadata
struct stat statbuf ;
assert( stat(inputFilepath,&statbuf ) != -1 );
// skip directories
if ( ( statbuf.st_mode & S_IFMT ) == S_IFDIR )
{
continue;
}
// open input file
int inputFile_fd = open(inputFilepath, O_RDONLY);
if (inputFile_fd < 0) {
printf("Failed opening file in input directory, %s. Error: %s\n", inputFilepath, strerror(errno));
return errno;
}
// Temp file name
char outputFilePath[200] ;
// full path to file
sprintf(outputFilePath, "%s/%s",outputDirPath, dirEntity->d_name) ;
// open input file
int outputFile_fd = open(outputFilePath, O_WRONLY | O_CREAT | O_TRUNC);
if (outputFile_fd < 0) {
printf("Failed opening file in output directory, %s. Error: %s\n", outputFilePath, strerror(errno));
return errno;
}
char inputFileBuf[BUFFERSIZE];
while (read(inputFile_fd, inputFileBuf, BUFFERSIZE) == BUFFERSIZE){
char keyFileBuf[BUFFERSIZE];
if (read(key_fd, keyFileBuf, BUFFERSIZE) == 0) {
assert(!close(key_fd));
key_fd = open(keyFilePath, O_RDONLY);
if (key_fd < 0) {
printf("Failed opening Key file %s. Error: %s\n", keyFilePath, strerror(errno));
return errno;
}
read(key_fd,keyFileBuf, BUFFERSIZE);
}
char outputToWrite[BUFFERSIZE];
int i;
for(i = 0; i < BUFFERSIZE; i++){
outputToWrite[i] = keyFileBuf[i] ^ inputFileBuf[1];
}
if( write(outputFile_fd, outputToWrite, BUFFERSIZE) == -1){
printf("Failed writing to output file, %s. Error: %s\n", outputFilePath, strerror(errno));
return errno;
};
}
if(close(inputFile_fd) ); // close key file
}
closedir(inputDir_dfd); // close Dir
assert(!close(key_fd)); // close key file
}
thanks.

how to get the source file's (the file which I want to copy) and the copied file's information in C

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

Resources