I was trying to make a program to copy files from the documents folder on my Linux machine into the documents folder onto a USB with Windows on it. So far, it only creates files without copying any actual data to them, but that's not the problem I'm trying to solve right now. The code looks like this (there are no real errors, more information is written under the code):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
int main()
{
DIR *folder;
struct dirent *entry;
int files = 0;
folder = opendir("/home/ubuntumate/Documents");
if(folder == NULL)
{
perror("Unable to read directory");
return(1);
}
while( (entry=readdir(folder)) )
{
if(entry->d_type == DT_REG)
{
files++;
char newfilename[100];
snprintf(newfilename, sizeof(newfilename), "/media/ubuntumate/7494348594344C3C/Users/John/Documents/%s", entry->d_name);
FILE *clone = fopen(newfilename, "w");
fclose(clone);
}
}
closedir(folder);
return(0);
}
You may have noticed that I hard-coded the media's location, including both the username and the media's id. (my username is "ubuntumate" because I'm on a virtual machine running Ubuntu MATE). The question I'm asking is how do i get a list of all the medias attached to the machine, so that this program can still work with a different user, and on a different USB that also contains windows?
You can check whether a block device is removable under the sys hierarchy. E.g. something like
$ stat /dev/sdc|grep Device
Device: 6h/6d Inode: 347 Links: 1 Device type: 8,20
From here you see the device is major number 8, minor 20 (in hex). Then check
$ cat /sys/dev/block/8\:32/removable
0
Never mind, I found an answer. I can just list all the folders in the media/[username] folder. There are a lot of tutorials on getting the username so that one wont be a problem, cuz i can just search it up.
Related
I have a embedded device running Linux Angstrom. I need to detect a USB drive. So when a USB drive is inserted, I need to automatically copy data from the USB to internal memory of the embedded device.
To detect the USB, I am using below code:
DIR* dir = opendir("/media/sda1/");
if (dir)
{
printf("USB detected\n");
//rest of the code
//to copy data from the USB
}
This works normally but sometimes after copying is done, I remove the USB but the name of the mount point (sda1) remains there. So after removing the USB, it again try to copy the data (because sda1 is there in media) and then shows error because physical no USB is connected. What is the best way to detect if USB is connected and if connected then after copying how to eject it properly. Here I cannot use udisks because its not available for the linux angstrom I am using for this embedded device. So only generic linux commands will work.
Any help. Thanks
One naive approach is the following:
execute mount | grep /dev/sda1
parse the output: if there is no output, that means that sda1 is not mounted
You may have to adapt the code to your specific platform.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
/* launch a command and gets its output */
FILE *f = popen("mount | grep /dev/sda1", "r");
if (NULL != f)
{
/* test if something has been outputed by
the command */
if (EOF == fgetc(f))
{
puts("/dev/sda1 is NOT mounted");
}
else
{
puts("/dev/sda1 is mounted");
}
/* close the command file */
pclose(f);
}
return 0;
}
I am trying to figure out the file type of a file, without using external libs or the "file" command.
I have viewed a number of posts and threads, and they point to using the stat() function (unix man stat) and playing with the "st_mode" from the stat struct.
But I have no idea how to do this, nor am I able to find a good example of doing it.
For example the program takes in a file F, I want to be able to read F similar to the program below and give similar output. And the filetype of F is a PDF, but it does not have the extension on it.
FURTHER EXAMPLE: If I have foo.pdf, but I changed the extension to *.png (foo.png) I can pass my program "foo.png" and say it is infact a .pdf file.
When a file is created, it makes a "magic number", example with a PDF, the magic number of PDF files start with "%PDF" (hex 25 50 44 46)."
How can I use the magic number to figure out the filetype.
I understand some type of table will need to be made at my end, to support files. And I am only doing a small handful <10.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void errorInput()
{
fprintf(stderr, "\nYou have received this message due to an error. \n");
fprintf(stderr, "Please type 'filetype <file>' to properly execute the program.\n");
fprintf(stderr, "Thank you and have a fine day! \n\n");
exit(0);
}
int main(int argc, char *argv[])
{
char command[128];
if (argc == 2)
{
strcpy(command, "file ");
strcat(command, argv[1]);
system(command);
}
else
{
errorInput();
}
return 0;
}
Thank You in advance!
Like Jonathon Reinhart Pointed, don't try to reinvent the wheel use libmagic:
#include <stdio.h>
#include <magic.h>
int main(void) {
struct magic_set *magic = magic_open(MAGIC_MIME|MAGIC_CHECK);
magic_load(magic,NULL);
printf("Output1: '%s'\n",magic_file(magic,"ValgrindOut.xml"));
printf("Output2: '%s'\n",magic_file(magic,"program"));
printf("Output3: '%s'\n",magic_file(magic,"Chapter9.pdf"));
printf("Output4: '%s'\n",magic_file(magic,"test.txt"));
printf("Output5: '%s'\n",magic_file(magic,"linux-3.17.tar.xz"));
printf("Output6: '%s'\n",magic_file(magic,"gcc-5.2.0.tar.gz"));
printf("Output7: '%s'\n",magic_file(magic,"/home/michi"));
return 0;
}
Compile:
gcc -o program program.c -lmagic
Output:
Output1: 'application/xml; charset=us-ascii'
Output2: 'application/x-executable; charset=binary'
Output3: 'application/pdf; charset=binary'
Output4: 'text/plain; charset=utf-8'
Output5: 'application/x-xz; charset=binary'
Output6: 'application/gzip; charset=binary'
Output7: 'inode/directory; charset=binary'
First, you need to include sys/stat.h
Next, you need to declare a struct stat in your code:
struct stat s
Next, you pass a pointer to your stat structure along with the file/object name:
returnval = stat("filename", &s);
Check the return value, you'll get < 0 on error. If no error the object/file exists, we can use a macro function to determine the file type:
if (S_ISREG(s.st_mode))
/* Regular text file... */
else if (S_ISDIR(s.st_mode))
/* Is a directory.... */
I suggest you have a look at the man page (man 3 stat) and it will give you all of the types that st_type may potentially be (it can be used to identify files, directories, block devices, sym links, etc)
Another very useful member of the stat struct is st_size which gives you a files size in bytes.
ETA - the stat() system call won't tell you if a file is a PDF or anything like that - normally we'd use the extension, if there is no extension and you're trying to identify specific file formats then stat() won't be of much use to you.
Most files usually will have a portion called as Header/MetaData. It is in this portion/segments of the file which will contain details about the file it self.Also, these Headers/MetaData Segments will also contain the Signature to identify the file type. But be aware most of these Signatures will be in an Hex Signature format
Example
PDF Signature - 25 50 44 46(In Hex) or %PDF
JPEG Signature - Start FF D8 and end of file FF D9
So, Basically you need to open the file in a binary format and parse the file structure and compare it to see if it matches with any one of the file types you define in your program.Like suppose you wanna check if it's pdf file then you need to first open the file in binary mode then scan the file till you get the bytcode/hex code which matches the bytcode/hex code of a pdf file. Use the C fopen() function in binary mode i.e "rb".
Or you can open the file normally without binary mode like this,
unsigned int data;
data=fgetc(pfile);
You might want to look into this for further details,
Magic Number
File Signatures
I am using windows 7 64bit OS and DOS box turbo C++. I want to write a simple program to read a text file containing a single integer from E drive of my machine. The file name is t.txt. I have written the following code:
#include <stdio.h>
#include <conio.h>
#include <dir.h>
#include <stdlib.h>
int main(void)
{
FILE *input;
int data;
if ( (input = fopen("E:\\t.txt","r")) == NULL)
printf("Error: Unable to open");
else
{
fscanf(input,"%d",&data);
printf("successfully read in %d",data);
}
fclose(input);
input=NULL;
getch();
}
But this program is unable to access the file and every time it gives an output like:
Error: Unable to open
What is the problem with this code?
Please help.
Yes!!! got it.. Thank you Michael. I tried to mount E: in dosbox and it has run fine.
Problem must be with the usage of file path
Solution given below worked with me in Ubuntu
just try it
char *file = "E:\\t.txt";
FILE *fp = fopen(file, "r");
And verify whether you are using the correct path
Have a good day
How can I get directory name if I know it's inode number? Need the code. Thanks.
the below code passed dir_name by .. , then I got it's i-node number, but what I also want is the directory name.
/*child stat*/
stat(dir_name, &sb);
if (stat(dir_name, &sb) == -1) {
perror("stat");
exit(EXIT_FAILURE);
}
childIno = (long) sb.st_ino;
Unless you have an index mapping inodes to names, you will have to recursively walk the directory structure until you find a name with the inode you're looking for (which you may not find).
If one part of your program already knows the name of the directory, you should find a way to pass it into your code.
Not sure you can easily get it from the inode number alone. Lots of things could point to the same inode (hard links, soft links etc). If you are just looking for a path you can print out and feel good about, you could use realpath. Example below compiles readily on Ubuntu 12.04 and should work on BSD systems as well. realpath will eat all of the ../ and ./ stuff resulting in a decent looking path (though not necesarily a unique path.
#include <stdlib.h>
#include <stdio.h>
int main( int argc, char *argv[] ){
char *test_path = realpath( "..", NULL );
if ( test_path ) {
printf( "Path resolves to %s\n", test_path );
} else {
printf( "Couldn't resolve path\n" );
}
exit(0);
}
I have suppose two text file abc.txt and def.txt in folder "my". I have a programme which directly goes to that folder and search particular file and if that particular file find out then how to access that file's information.
I know how to read write file in C through file handling but I have no idea how to search particular file and after that read that particular file to match particular string in file.
**All these things access through file handling in C.**
So please if any one have any solution I will be thankful for that
Example will be best way to understand .
Thanks in advance
To get a listing of the files in a directory in Linux, you can use the 'opendir', 'readdir' and 'closedir' functions from 'dirent.h'. For example:
#include <dirent.h>
#include <stdio.h>
int ListDir(const char *pDirName)
{
DIR *pDir;
struct dirent *pEntry;
pDir = opendir(pDirName);
if (!pDir)
{
perror("opendir");
return -1;
}
while ((pEntry = readdir(pDir)) != NULL)
{
printf("%s\n", pEntry->d_name);
}
closedir(pDir);
return 0;
}