How to generate random file name for socket under Linux? - c

I want to make a small program which use local namespace socket and I will need to use temporary file name as address of the socket.
So how to generate random file name under Linux?
+ I'm using the C programming language under Debian Linux.
+ Acoording to the GNU C Library Reference,tmpname is not safe.But the safe ones tmpfile and mkstemp create and open the generated file.Is there any safe and non-create-open to this.In other words, the function should forbidden any other request to create the generated file name under specific directory.
thanks.

If you're doing this in C, use mkdtemp to create a directory, and put your socket inside this directory.
Other functions such as tmpnam or mktemp are insecure; since they don't create and open the temp file for you, it's easy to be vulnerable to following a pre-existing symlink (placed by an attacker who guessed your temp filename) to some important file (like /etc/passwd), overwriting it.
Note that there's no way to 'lock' a path - all you can do is create something there. If you need to put a socket there eventually, using a directory as a placeholder is your best bet.

There is mktemp program which is available as part of GNU coreutils. See it's manpage for details.
Typical usage is as simple as this:
TEMPDIR=$(mktemp -d)
echo $TEMPDIR
touch $TEMPDIR/yourfile.txt
(As noted in other answer it is only safe to create a directory.)

You didn't specify the language you are using, but assuming it is a C/C++ dialect (or some other language with access to the C runtime library), you could use the tmpnam function.
There are some issues with tmpnam, the most serious of which is probably that the temporary file name you get back isn't actually "locked" until you use it to create a file, so theoretically some other process could create the file out from under you. You also have to make absolutely sure the buffer you pass tmpnam has enough space to hold the longest path your OS can support.
These days it is recommended that you call tmpfile instead. This will create the file for you in one (hopefully atomic) operation, and give you back a file handle. Another nice benefit is that the file is deleted for you automatically when you close it. No muss, no fuss.

Play with /dev/random.
A quick search on google gave me this hit:
< /dev/urandom tr -dc A-Za-z0-9 | head -c8
If you would like to do the same in C,
just open /dev/random and convert it into a string (ignore non valid chars).

Related

How would I know that file is opened and it is saved after some writing operation using C code?

I have a set of configuration files (10 or more), and if user opens any of these file using any editor (e.g vim,vi,geany,qt,leafpad..). How would I come to know that which file is opened and if some writing process is done, then it is saved or not (using C code).
For the 1st part of your question, please refer e.g. to How to check if a file has been opened by another application in C++?
One way described there is to use a system tool like lsof and call this via a system() call.
For the 2nd part, about knowing whether a file has been modified, you will have to create a backup file to check against. Most editors already do that, but their naming scheme is different, so you might want to take care of that yourself. How to do that? Just automatically create a (hidden) file .mylogfile.txt if it does not exist by simply copying mylogfile.txt. If .mylogfile.txt exists, is having an older timestamp than mylogfile.txt, and differs in size and/or hash-value (using e.g. md5sum) your file was modified.
But before re-implementing this, take a look at How do I make my program watch for file modification in C++?

C Programming: How to create a parent directory and insert files manually?

My goal is to, inside my C program, make a new directory. Within this directory, I want to create 15 simple text files. The part that I am stuck on is how to generate the 15 text files inside the newly created directory. I have created the new directory like this:
mkdir("new_dir", 0755);
But I am unsure of how to create a text file within it (in the same program). Any tips for this?
I am guessing you are on some POSIX system. The C11 standard (read n1570) does not know about directories (an abstraction provided by your operating system). If you are on Windows, it has a different WinAPI (you should then use CreateDirectory)
First, your call to mkdir(2) could fail (for a variety of reasons, including the fact that the directory did already exist). And very probably, you actually want to create the directory in the home directory, or document that you are creating it in the current working directory (e.g. leave the burden of some appropriate and prior cd shell builtin to your user). Practically speaking, the directory path should be computed at runtime as a string (perhaps using snprintf(3) or asprintf(3)).
So if you wanted to create a directory in the home directory of the user (remember that ~/foo/ is expanded by the shell during globbing, see glob(7)...; you need to fetch the home directory from environ(7)), you would code something like:
char pathbuf[256];
snprintf(pathbuf, sizeof(pathbuf), "%s/new_dir", getenv("HOME"));
to compute that string. Of course, you need to handle failure (of getenv(3), or of snprintf). I am leaving these checks as an exercise. You might want to keep the result of getenv("HOME") in some automatic variable.
Then you need to make the directory, and check against failure. At the very least (using perror(3) and see errno(3)):
if (mkdir (pathbuf, 0750)) { perror(pathbuf); exit(EXIT_FAILURE); }
BTW, the mode passed to mkdir might not allow every other user to write or access it (if it did, you could have some security vulnerability). So I prefer 0750 to yours 0755.
At last you need to create files inside it, perhaps using fopen(3) before writing into them. So some code like
int i = somenumber();
snprintf(pathbuf, sizeof(pathbuf),
"%s/new_dir/file%d.txt", getenv("HOME"), i);
FILE* f = fopen(pathbuf, "w");
if (!f) { perror(pathbuf); exit(EXIT_FAILURE); };
As Jonathan Leffler wisely commented, there are other ways.
My recommendation is to document some convention. Do you want your program to create a directory in the current working directory, or to create it in some "absolute" path, perhaps related to the home directory of your user? If your program is started by some user (and is not setuid or doesn't have root permissions, see credentials(7)) it is not permitted to create directories or files at arbitrary places (see hier(7)).
If on Linux, you'll better read some system programming book like ALP or newer. If you use a different OS, you should read the documentation of its system API.

How to safely and portably create temp file AND get its name

I'm working with some legacy code which passes around the name of a file. I'd like to create a temp file and give the legacy code the name of the file to be opened later using legacy functions. tmpnam is unsafe due to the race case between getting the name and creating the file. mkdir isn't portable to Windows and doesn't let me have the name of the file. How can I create a temp file safely, portably, and with retention of file name?
In windows GetTempFileName function. In Linux if you do not more than 25 files (bug in some implementations) mkstemp family of functions or tmpfile

Copying files from one folder to another in C Program

I want to copy some files from one folder to other folder and before copying or replacing the files I want to take backup from destination folder only those file which are I am trying to copy in to source file to destination file.
This is what I want to do but is this possible in pure C-language?.
First of all you should say on which platform you want to do that.
I'm not that familiar with Windows so what i'll be saying only applies to Linux (maybe it works on windows as well but I doubt it).
Have a look on man opendir and man readdir and those are the only things you need to do what you want (you obviously will also need to open/read/write and close but I imagine that you know that).
There's no native way in C to do that. You need platform-specific code. The simplest way to achieve that is to use the system() function
system("copy C:\\Windows\\notepad.exe D:\\"); // Windows
or
system("cp ~/myfile.txt ~/mycopiedfile.txt"); // *nix
But for better performance and/or more control over the result you need to call the corresponding APIs if available (like CopyFile() on Windows), or copy the file on your own by reading from source to a buffer with fread() then write to the destination with fwrite()
See Is there a POSIX function to copy a file?

C - Reading multiple files

just had a general question about how to approach a certain problem I'm facing. I'm fairly new to C so bear with me here. Say I have a folder with 1000+ text files, the files are not named in any kind of numbered order, but they are alphabetical. For my problem I have files of stock data, each file is named after the company's respective ticker. I want to write a program that will open each file, read the data find the historical low and compare it to the current price and calculate the percent change, and then print it. Searching and calculating are not a problem, the problem is getting the program to go through and open each file. The only way I can see to attack this is to create a text file containing all of the ticker symbols, having the program read that into an array and then run a loop that first opens the first filename in the array, perform the calculations, print the output, close the file, then loop back around moving to the second element (the next ticker symbol) in the array. This would be fairly simple to set up (I think) but I'd really like to avoid typing out over a thousand file names into a text file. Is there a better way to approach this? Not really asking for code ( unless there is some amazing function in c that will do this for me ;) ), just some advice from more experienced C programmers.
Thanks :)
Edit: This is on Linux, sorry I forgot to metion that!
Under Linux/Unix (BSD, OS X, POSIX, etc.) you can use opendir / readdir to go through the directory structure. No need to generate static files that need to be updated, when the file system has the information you want. If you only want a sub-set of stocks at a given time, then using glob would be quicker, there is also scandir.
I don't know what Win32 (Windows / Platform SDK) functions are called, if you are developing using Visual C++ as your C compiler. Searching MSDN Library should help you.
Assuming you're running on linux...
ls /path/to/text/files > names.txt
is exactly what you want.
opendir(); on linux.
http://linux.die.net/man/3/opendir
Exemple :
http://snippets.dzone.com/posts/show/5734
In pseudo code it would look like this, I cannot define the code as I'm not 100% sure if this is the correct approach...
for each directory entry
scan the filename
extract the ticker name from the filename
open the file
read the data
create a record consisting of the filename, data.....
close the file
add the record to a list/array...
> sort the list/array into alphabetical order based on
the ticker name in the filename...
You could vary it slightly if you wish, scan the filenames in the directory entries and sort them first by building a record with the filenames first, then go back to the start of the list/array and open each one individually reading the data and putting it into the record then....
Hope this helps,
best regards,
Tom.
There are no functions in standard C that have any notion of a "directory". You will need to use some kind of platform-specific function to do this. For some examples, take a look at this post from Cprogrammnig.com.
Personally, I prefer using the opendir()/readdir() approach as shown in the second example. It works natively under Linux and also on Windows if you are using Cygwin.
Approach 1) I would just have a specific directory in which I have ONLY these files containing the ticker data and nothing else. I would then use the C readdir API to list all files in the directory and iterate over each one performing the data processing that you require. Which ticker the file applies to is determined only by the filename.
Pros: Easy to code
Cons: It really depends where the files are stored and where they come from.
Approach 2) Change the file format so the ticker files start with a magic code identifying that this is a ticker file, and a string containing the name. As before use readdir to iterate through all files in the folder and open each file, ensure that the magic number is set and read the ticker name from the file, and process the data as before
Pros: More flexible than before. Filename needn't reflect name of ticker
Cons: Harder to code, file format may be fixed.
but I'd really like to avoid typing out over a thousand file names into a text file. Is there a better way to approach this?
I have solved the exact same problem a while back, albeit for personal uses :)
What I did was to use the OS shell commands to generate a list of those files and redirected the output to a text file and had my program run through them.
On UNIX, there's the handy glob function:
glob_t results;
memset(&results, 0, sizeof(results));
glob("*.txt", 0, NULL, &results);
for (i = 0; i < results.gl_pathc; i++)
printf("%s\n", results.gl_pathv[i]);
globfree(&results);
On Linux or a related system, you could use the fts library. It's designed for traversing file hierarchies: man fts,
or even something as simple as readdir
If on Windows, you can use their Directory Management API's. More specifically, the FindFirstFile function, used with wildcards, in conjunction with FindNextFile

Resources