I am trying to use zlib and minizip. When I build 6 projects in one soltuion which are included in archive I downloaded everything works and project will create exe files (minizip and miniunz). Here is the problem, I don't know how to use miniunz and minizip source codes in my application and google isn't helping. Can somebody, who has experience with these libs, provide step by step tutorial how to include these lib in my application?
Or if you have other libraries to work with password protected files and can provide some tutorial how to include it in project that will help too, I tried to find something but there was no tutorial how to install them to projects
Thanks
Code based on minizip unzip.c.
include stdio.h zip.h unzip.h
First, create a zip with a file inside with a password.
The zip file must be in the same directory as the executable.
Run the program from a prompt in the directory of the generated program.
This example only extracts the first file!
/*-----------start-------------- */
/*Tries to open the zip in the current directory.*/
unzFile zfile = unzOpen("teste.zip");
if(zfile==NULL)
{
printf("Error!");
return;
}
printf("OK Zip teste.zip opened...\n");
int err = unzGoToFirstFile(zfile);/*go to first file in zip*/
if (err != UNZ_OK)
{
printf("error %d with zipfile in unzGoToFirstFile\n", err);
unzClose(zfile);/*close zip*/
}
/*At this point zfile points to the first file contained in the zip*/
char filename_inzip[256] = {0};/* The file name will be returned here */
unz_file_info file_info = {0};/*strcuture with info of the first file*/
err = unzGetCurrentFileInfo(zfile, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
if (err != UNZ_OK)
{
printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
}
else
{
int len = 8192;/*size of chunk*/
char buffer[8192]={0};/*buffer used to save uncompressed data*/
printf("name of first file is :%s\n",filename_inzip);
printf("uncompressed_size = %d\n",file_info.uncompressed_size);
/*Use your password here, the same one used to create your zip */
err = unzOpenCurrentFilePassword(zfile, "yourpassword");
if (err != UNZ_OK)
printf("error %d with zipfile in unzOpenCurrentFilePassword\n", err);
else
printf("password ok\n");
FILE *fp = fopen(filename_inzip, "wb");/*file for data binary type*/
if (fp != NULL)
{
do
{/*read the current file returned by unzGoToFirstFile to buffer in chunks of the 8192*/
err = unzReadCurrentFile(zfile, &buffer, len );
if (err < 0)
{
printf("error %d with zipfile in unzReadCurrentFile\n", err);
break;
}
if (err == 0)
break;
/*Save the chunk read to the file*/
if (fwrite(&buffer, err, 1, fp) != 1)/*if error break*/
{
printf("error %d in writing extracted file\n", errno);
err = UNZ_ERRNO;
break;
}/*else continue*/
}
while (err > 0);
/*close file*/
fclose(fp);
}
}
unzClose(zfile);
Related
I am trying to write a simple program (toy example) that copies a file from a remote host to the local machine.
It works when I try to copy a txt file, but not for files like mp4.
Here is my code, which is basically parts stitched together from the tutorial: https://pastebin.com/0FPrmeDx
This is where the error happens:
int scp_receive(ssh_session session, ssh_scp scp)
{
int rc;
int size, mode;
char *filename, *buffer;
rc = ssh_scp_pull_request(scp);
if (rc != SSH_SCP_REQUEST_NEWFILE)
{
fprintf(stderr, "Error receiving information about file: %s\n",
ssh_get_error(session));
return SSH_ERROR;
}
size = ssh_scp_request_get_size(scp);
filename = strdup(ssh_scp_request_get_filename(scp));
mode = ssh_scp_request_get_permissions(scp);
printf("Receiving file %s, size %d, permisssions 0%o\n",
filename, size, mode);
free(filename);
buffer = malloc(size);
if (buffer == NULL)
{
fprintf(stderr, "Memory allocation error\n");
return SSH_ERROR;
}
ssh_scp_accept_request(scp);
rc = ssh_scp_read(scp, buffer, size);
if (rc == SSH_ERROR)
{
fprintf(stderr, "Error receiving file data: %s\n",
ssh_get_error(session));
free(buffer);
return rc;
}
printf("Done!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
int filedesc = open("/home/user/video.mp4", O_WRONLY | O_CREAT);
if (filedesc < 0) {
return -1;
}
write(filedesc, buffer, size);
free(buffer);
close(filedesc);
rc = ssh_scp_pull_request(scp);
if (rc != SSH_SCP_REQUEST_EOF)
{
fprintf(stderr, "Unexpected request: %s\n",
ssh_get_error(session));
return SSH_ERROR;
}
return SSH_OK;
}
Error is fired with the code:
rc = ssh_scp_pull_request(scp);
if (rc != SSH_SCP_REQUEST_EOF)
{
fprintf(stderr, "Unexpected request: %s\n",
ssh_get_error(session));
return SSH_ERROR;
}
This is the error that I get:
Unexpected request: ssh_scp_pull_request called under invalid state
I tried to figure it out, but I couldn't make any progress on it.
Update 1:
The size of the copied file is exactly the same as of the source file both for txt and mp4 files. However, the copied file seems to be largely empty...
When copied, the permissions are changed from -rwxr-xr-x to --wxr-----.
Update 2:
It seems that the file size plays a major role here. Very small files (10-15kb) are copied without problems. Bigger files are not copied and produce the above mentioned error...
You cannot expect, that ssh_scp_read() reads the whole data in a single call to it. You have to iterate, until no more data is left to read:
int r = 0;
while (r < size) {
int st = ssh_scp_read(scp, buffer+r, size-r);
r += st;
}
Now, a subsequent call to ssh_scp_pull_request(scp) should succeed.
I want to do a error check in a openFile Function in C and on errno:2 I want to recursivly call again the same function.
I don't get the right answer, if I want to do fputs() after opened the file I get a Error (Bad file descriptor)
Here is my code:
void openFile(FILE **fstream, char* path, char* mode) {
*fstream = fopen(path, mode);
if(*fstream == NULL) {
printf("\nError number %2d : ",errno);
perror("Error opening file: ");
switch (errno) {
case 2:
printf("Creating file %s now...\n", path);
*fstream = fopen(path, "a+"); //Creating file in append-mode
if (fstream == NULL) {
perror("Couldn't open the file!\nError");
exit(EXIT_FAILURE);
}
fclose(*fstream); //Closing filestream
openFile(fstream, path, mode); //Recursive call of openFile() to re-open in read-mode
/* freopen(path,mode,fstream) */ //Doesn't work either
break;
default:
exit(EXIT_FAILURE);
break;
}
} else if (*fstream != NULL) {
printf("Successfully opened %s\n", path);
}
}
The call:
openFile(&fp, path,"r");
if (fputs("blabla\nblabla\n",fp) == EOF) {
perror("Unable to write file with fputs()");
}
What I'm doing wrong? I think it's at the point of the recursive call of the function, but what I have to do here? I don't get it..
Output is:
> .\a
Content of path: test.txt
Error number 2 : Error opening file: : No such file or directory
Creating file test.txt now...
Successfully opened test.txt
Unable to write file with fputs(): Bad file descriptor
PS: I am a beginner with C, I've read and youtubed a lot about pointer, but I don't get the mistake.
Thank you in advance
You opened the file with "r" yet you're attempting to write. You need "w" instead.
I have written a code which read file from remote device using libssh scp APIs.
I have a specific requirement wherein I want to scp a .tar file from a remote device.
I am able to read .tar content into a buffer, but I am not sure how to create .tar file out of that buffer.
Any help would be appreciated.
Thanks.
Code snippet:
char *t_filename, t_buffer[32768];
....
t_rc = ssh_scp_pull_request(t_scp);
switch(t_rc)
{
case SSH_SCP_REQUEST_NEWFILE:
t_filesize = ssh_scp_request_get_size(t_scp);
t_filename = strdup(ssh_scp_request_get_filename(t_scp));
t_filemode = ssh_scp_request_get_permissions(t_scp);
fprintf(stderr, "Receiving file %s, size %d, permisssions 0%o\n", t_filename, t_filesize, t_filemode);
ssh_scp_accept_request(t_scp);
t_rc = ssh_scp_read(t_scp, t_buffer, sizeof(t_buffer));
if(t_rc == SSH_ERROR)
{
fprintf(stderr, "Error receiving file data: %s\n", ssh_get_error(in_session));
ssh_scp_close(t_scp);
ssh_scp_free(t_scp);
return t_rc;
}
fprintf(stderr, "Bytes received = %d\n", t_rc);
FILE *fptr = fopen(t_filename, "w");
if(NULL != fptr)
{
fwrite(t_buffer,sizeof(t_buffer),1,fptr);
fclose(fptr);
}
break;
}
Create a local file using either open() or fopen(), then feed in the raw data using write() or fwrite(). When finished, call close() or fclose().
Updated your code-snippet, not compile tested, but gives you the idea.
The remote read should be repeated until the whole file has been received, also, you might receive chunks that are smaller than sizeof (t_buffer), so do not write out more data than you received.
char *t_filename, t_buffer[32768];
....
t_rc = ssh_scp_pull_request(t_scp);
switch(t_rc)
{
case SSH_SCP_REQUEST_NEWFILE:
t_filesize = ssh_scp_request_get_size(t_scp);
t_filename = strdup(ssh_scp_request_get_filename(t_scp));
t_filemode = ssh_scp_request_get_permissions(t_scp);
fprintf(stderr, "Receiving file %s, size %d, permisssions 0%o\n", t_filename, t_filesize, t_filemode);
FILE *fptr = fopen(t_filename, "w");
if(NULL == fptr)
{
fprintf (stderr, "Error opening local file: %s, error %s\n", t_filename, strerror (errno));
ssh_scp_deny_request (t_scp, "Unable to open local file");
break;
}
ssh_scp_accept_request(t_scp);
do
{
t_rc = ssh_scp_read(t_scp, t_buffer, sizeof(t_buffer));
if(t_rc == SSH_ERROR)
{
fprintf(stderr, "Error receiving file data: %s\n", ssh_get_error(in_session));
fclose(fptr);
ssh_scp_close(t_scp);
ssh_scp_free(t_scp);
return t_rc;
}
fprintf(stderr, "Bytes received = %d\n", t_rc);
if (fwrite(t_buffer,t_rc,1,fptr) != 1)
{
fprintf (stderr, "Error writing file data: %s\n", strerror (errno));
fclose(fptr);
ssh_scp_close(t_scp);
ssh_scp_free(t_scp);
return t_rc;
}
} while (t_rc != 0);
fclose (fptr);
break;
}
I have created a Client/Server application in C by using the SSL library. the issue i am facing is each time i send a file there are some bytes missing in the start of file.
let suppose the text file which i am sending contains
123456789
and when the client receive the file it would contains
56789
Server-Code
void sendFile(SSL* ssl)
{
char response[2048] = {0};
int read = 0;
FILE* fd;
fd = fopen("snt.txt","rb");
if (fd == NULL)
{
printf("file loading failed\n");
return;
}
while ((read=fread(response,sizeof(char),1024,fd)) > 0)
{
SSL_write(ssl,response,read);
printf("read :%d\n",read);
//puts(response);
//printf("***Data Sent***\n");
memset(response,0,1024);
}
printf("***Data Sent***\n");
fclose(fd);
}
Client Code
FILE *ft;
char filebuf[2048];
int read = 0;
int error_check=0;
ft = fopen("rcv.txt","ab");
if (ft == NULL)
{
printf("Can not open file to write\n");
return -1;
}
memset(filebuf,0,2048);
int cnk=1;
while ((error_check=BIO_read(bio,&read,sizeof(int)))>0)
{
//printf("%d read\n",read);
if (error_check==0)
break;
if (read==0)
break;
BIO_read(bio,filebuf,read);
printf("%d Chunk Recieved\n",cnk++);
//puts(filebuf);
fwrite(filebuf,sizeof(char),strlen(filebuf),ft);
memset(filebuf,0,2048);
}
printf("***File Recieved***");
fclose(ft);
the other issue is client side is not terminated, control doesn't get away from the while-loop, kindly guide me how can i tackle these issues
Assuming size(int) is 4, I'd say the 1st 4 bytes are read by this line:
while ((error_check=BIO_read(bio,&read,sizeof(int)))>0)
That leaves the rest of the data sent to this line:
BIO_read(bio,filebuf,read);
The latter reads it into filebuf which then is written to the file rcv.txt.
I'm trying to write a function in C to copy the contents of a directory to another directory. Here is what I have so far:
void *copydirectory(void *arg1, void *arg2)
{
int error;
struct dirent *direntp;
DIR *dirp_source, *dirp_destination;
char *source, *destination;
copy_t copy;
char filename[MAXNAME];
// Set directory arguments
source = arg1;
destination = arg2;
fprintf(stderr, "Source directory is %s and destination directory is %s\n", source, destination);
// Open directories
if ((dirp_source = opendir(source)) == NULL)
{
fprintf(stderr, "Failed to open %s\n", source);
return 1;
}
if ((dirp_destination = opendir(destination)) == NULL)
{
perror("Failed to open destination directory");
return 1;
}
// Read files in directory
while ((direntp = readdir(dirp_source)) != NULL)
{
copy.tid = pthread_self();
fprintf(stderr, "now at line 64\n");
// Copy source filename
if (snprintf(filename, MAXNAME, direntp->d_name) == MAXNAME)
{
fprintf(stderr, "Input filename %s is too long", direntp->d_name);
continue;
}
fprintf(stderr, "now at line 73\n");
fprintf(stderr, "%s\n", filename);
// Open file for reading
if ((copy.args[0] = open(filename, R_FLAGS)) == -1)
{
fprintf(stderr, "Failed to open source file %s: %s\n", filename, strerror(errno));
continue;
}
// Create destination filename for writing
if (snprintf(filename, MAXNAME, "%s", direntp->d_name) == MAXNAME)
{
fprintf(stderr, "Output filename %s is too long\n", direntp->d_name);
continue;
}
fprintf(stderr, "%s\n", filename);
// Open file for writing
if ((copy.args[1] = open(filename, W_FLAGS, W_PERMS)) == -1)
{
fprintf(stderr, "Failed to open destination file %s: %s\n", filename, strerror(errno));
continue;
}
if (error = pthread_create((©.tid), NULL, copyfilepass, copy.args))
{
fprintf(stderr, "Failed to create thread: %s\n", strerror(error));
copy.tid = pthread_self();
}
}
// Close directory
while ((closedir(dirp_source) == -1) && (errno = EINTR));
fprintf(stderr, "Successfully copied all files in directory \n");
}
Now, for testing I simply have 2 directories in the folder named dir1 and dir2. dir1 contains 3 files: file1, file2, file3.
But, when I compile and run the code, I get these messages:
./
./
Failed to open destination file .: is a directory
Failed to open source file file2: No such file or directory
Failed to open source file file3: No such file or directory
../
../
Failed to open destination file .: is a directory
Failed to open source file file1: No such file or directory
Anyone have any suggestions on what's wrong?
Failed to open destination file .: is a directory
You see this because your source directory contains links called "." and ".." to itself and its parent directory respectively. You should specifically check for and avoid these entries.
Failed to open source file file2: No such fle or directory
You see this because you're trying to open a file called "file2" in the process's current working directory, but that doesn't exist - the file you're after is in the source directory. You need to build the filename taking this into account:
// Copy source filename
if (snprintf(filename, MAXNAME, "%s/%s", source, direntp->d_name) == MAXNAME)