C Programming. Printing current user - c

In C programming how do you get the current user and the current working directory.
I'm trying to print something like this:
asmith#mycomputer:~/Desktop/testProgram:$
(user) (computerName) (current directory)
I have the following code, but the username is showing as NULL. Any ideas what I'm doing wrong?
void prompt()
{
printf("%s#shell:~%s$", getenv("LOGNAME"), getcwd(currentDirectory, 1024));
}

Aside from the fact that you should be using the environment variable USER instead of LOGNAME, you shouldn't be using environment variables for this in the first place. You can get the current user ID with getuid(2) and the current effective user ID with geteuid(2), and then use getpwuid(3) to get the user name from the user ID from the passwd file:
struct passwd *p = getpwuid(getuid()); // Check for NULL!
printf("User name: %s\n", p->pw_name);
To get the current computer name, use gethostname(2):
char hostname[HOST_NAME_MAX+1];
gethostname(hostname, sizeof(hostname)); // Check the return value!
printf("Host name: %s\n", hostname);

On unix-like systems use the function getlogin from unistd.h.

This is not a C question but is more like a UNIX question. There is no portable way of getting the username and current working directory in C language.
However, by viewing your example, I can tell you are trying to print the current UNIX user name and current working directory.
If you need current working directory in UNIX check getcwd function.
If you need current user name you can either call a separate whoami process within your C program, or check the getuid function call.

This is going to be platform specific, as there is no intrinsic way in the C programming language to do this.
It looks like you're on a Unix-based system, so you'll probably want to get the environment variable USER which is usually the logon name.

you can also use
#include<stdlib.h>
main()
{
system("echo %username%"); /* This is for Windows
* instead use system("echo $USER"); for UNIX
*/
}

Note that this will work on a unix system only.
may be LOGNAME was not set as your environment variable
you can see the environment variables using the printenv command
printf("%s#shell:%s$", getenv("USER"),getenv("PWD"))
Also does the job.
but as mentioned you shouldn't rely on environment variables, rather use the standard c functions.If you really want to use them, first make sure it is set.

Related

Why is this C program doing nothing in Ubuntu?

My very simple C program just hangs and I don’t know why.
I am trying to make a simple executable to handle multiple monotonous actions for me every time I start a new programming session.
So I decided with something simple (below) yet every time I run it, the app just hangs, never returns. So I have to Ctrl-C out of it. I have added printf commands to see if it goes anywhere, but those never appear.
My build command returns no error messages:
gcc -o tail tail.c
Just curious what I am missing.
#include <stdio.h>
#include <unistd.h>
int main() {
chdir("\\var\\www");
return 0;
}
There are at least two problems with the source code:
It is unlikely that you have a sub-directory called \var\www in your current directory — Ubuntu uses / and not \ for path separators.
Even if there was a sub-directory with the right name, your program would change directory to it but that wouldn't affect the calling program.
You should check the return value from chdir() — at minimum:
if (chdir("/var/www") != 0)
{
perror("chdir");
exit(EXIT_FAILURE);
}
And, as Max pointed out, calling your program by the name of a well-known utility such as tail is likely to lead to confusion. Use a different name.
Incidentally, don't use test as a program name either. That, too, will lead to confusion as it is a shell built-in as well as an executable in either /bin or /usr/bin. There is also a program /bin/cd or /usr/bin/cd on your machine — it will check that it can change directory, but won't affect the current directory of your shell. You have to invoke it explicitly by the full pathname to get it to run at all because cd is another shell built-in.
Two things:
First, that's not what Linux paths look like
Second, check the return value from chdir()
ie
if (chdir("/var/www") != 0)
printf("failed to change directory");
Finally, the effect of chdir() lasts for the duration of the program. It will not change the current directory of your shell once this program finishes.
The other answers adequately cover the issues in your C code. However, the reason you are seeing it hang is because you chose the name tail for your program.
In Linux, tail is a command in /usr/bin in most setups, and if you just type tail at the command line, the shell searches the $PATH first, and runs this. Without any parameters, it waits for input on its stdin. You can end it by pressing control-d to mark the end of file.
You can bypass the $PATH lookup by typing ./tail instead.
$ tail
[system tail]
$ ./tail
[tail in your current directory]
It is a good idea to use ./ as a habit, but you can also avoid confusion by not naming your program the same as common commands. Another name to avoid is test which is a shell built-in for testing various aspects of files, but appears to do nothing as it reports results in its system return code.

getenv returns null when asked for the username?

I want to get the username using the stdlib functio getenv ()However I always get NULL here is the code that I have written:
#include<stdio.h>
#include<stdlib.h>
main()
{
char *hai;
printf("The current User name is\n");
hai="USER";
printf("%s\n",getenv(hai));
exit(0);
}
Does the value that getenv () returns depends on the machine that you are using to compile your code, and why the value returned is NULL?
On Windows, you'll need to use getenv("USERNAME"). The USER/USERNAME environment variable is not standardized, and you won't find an environment variable named USER on Windows unless you set it yourself.
This page talks about the return value for getenv(): "A C-string with the value of the requested environment variable, or a null pointer if such environment variable does not exist."
It looks like your "USER" environment variable is not set. Does it show up if you type set on the command line?

How to config ip address in embedded Linux?

I'm working on an embedded device running Linux (with BusyBox). I need to provide a command line tool to config static ip address. There are some limitations.
Using ifconfig won't do the job because it will get lost when
system rebooted.
With very limited resource, there's no GUI.
There is a vi text editor to modify Linux config file. But somehow that's not accepted either. Because the assumption is that the customers have no knowledge of how to use vi or deeper understanding to Linux. I need to provide a tool so that they can just press something like "ConfigMyIP 192.168.0.1 255.255.255.0" and the job is done.
Any idea how this can be done? (Using shell or C or both)
I came up with another solution myself. The general idea is to create a shell script that can config IP address in the system init directory. Here's the code:
#include <stdio>
#define MAXBUF 100
int main(int argc, char** argv)
{
FILE* f;
char content[MAXBUF];
f = fopen("/etc/init.d/configip", "w+");
strcat("#!/bin/sh\n", content);
strcat("ifconfig ", content);
strcat(argv[1], content);
strcat(" ", content);
strcat(argv[2], content);
strcat(" up", content);
fwrite(content, 1, strlen(content) + 1, f);
fclose(f);
return 0;
}
When this program was executed with arguments like "192.168.0.1 255.255.255.0", it will generate a shell script in etc/init.d:
#!/bin/sh
ifconfig 192.168.0.1 255.255.255.0 up
The script will be loaded every time Linux boots up.
If I understand it well, the target runs BusyBox.
So why not add a custom applet to provide this "simple interface" allowing the user to modify permanently the corresponding configuration files?
I think this option could fit better than an external program with the very constrained environment you describe.
Why not write a program in the language of your choice that prompts the user to enter the required IP address? Then, copy the existing configuration file to a backup version and create a new configuration file by reading the backup version a line at a time.
If the line specifies the IP address, then discard it and write a new line the specifies the new IP address, otherwise just write the existing line.
If it's important that your customers enter the parameters from the command line, as shown in your question, then have a look at the documentation of the language of your choice to see haw to access command line arguments. If you're using C, then have look at the argc and argv arguments that are passed to main.

UNIX (not Linux) password change with C

I already know that I can read the password structure (getpwnam etc.) but how can I alter the specific password. Do I have to lock the master.passwd and modify it directly or better make a copy from master.passwd modify this and make a file move after correct modifications?
At last, I don't want to make a system(usermod ...) because that invokes the shell and should be the last solution!
Thanks in advance
In C for Unix like Solaris or AIX , you can either :
Use PAM API if available. Here are some articles about it on Solaris.
Add a new password with putpwent
Change existing password with getpwent, crypt your new password and finish with endpwent
You'll see here a complete sample program to change a pasword for unix in C using putpwent & getpwent. AIX documentation seems to confirm it should also works on their OS.

getlogin() c function returns NULL and error "No such file or directory"

I have a question regarding the getlogin() function (). I tried to get the login name of my account from the c program using this function. But the function returns a NULL. Using perror shows that the error is "No such file or directory".
I don't get what is the problem. Is there a way to get user login name in a program.
Here is a sample code:
#include <stdio.h>
#include <unistd.h>
int main()
{
char *name;
name = getlogin();
perror("getlogin() error");
//printf("This is the login info: %s\n", name);
return 0;
}
And this is the output: getlogin() error: No such file or directory
Please let me know how to get this right.
Thanks.
getlogin is an unsafe and deprecated way of determining the logged-in user. It's probably trying to open a record of logged-in users, perhaps utmp or something. The correct way to determine the user you're running as (which might not be the same as the logged-in user, but is almost always better to use anyway) is getpwuid(getuid()).
Here is a good link I found explaining that it may not work: getlogin
Here is a quote from it:
Unfortunately, it is often rather easy to fool getlogin(). Sometimes it does not work at all, because some program messed up the utmp file
It works fine for me if I comment perror call.
From man:
getlogin() returns a pointer to a string containing the name of the user logged in on the controlling terminal of the process, or a null pointer if this information cannot be determined.'
So you should do:
#include <stdio.h>
#include <unistd.h>
int main()
{
char *name;
name = getlogin();
if (!name)
perror("getlogin() error");
else
printf("This is the login info: %s\n", name);
return 0;
}
According to the man page the error (ENOENT) means:
There was no corresponding entry in the utmp-file.
I typically use getpwent() along with a call to geteuid() and getegid(). This gives me all of the information that I might possibly need to know (at least as far as /etc/passwd has to offer) and tells me if I'm running as setuid / setgid, which is helpful when programming defensively.
I have written several programs for my company that outright refuse to work if someone tries to setuid them and change ownership to root, or refuse to run as root if being called by a system user (www-data, nobody, etc).
As others have said, reading from utmp is a very bad idea for this purpose.

Resources