Can I get SSID and MAC address from C code in Linux? - c

I am writing a C backup program for my Majaro Linux. It must backup files at a certain time in my home local server only if I am connecting to my home network. So I need to get an SSID and a MAC address a current network to decide if it is my network or not.
Is there Linux(Arch) default commands, C library functions or files, contain this information?
I already tried some Linux tools, ifconfig for example, but it is useless for me.
Help!

Done
Thank you all for your help, especially to Iliya Iliev and to this library.
It works perfectly.
It exactly what I've been searching for!
I just add it to my main project.
#include "../wifi_scan.h"
#include <stdio.h>
#include <unistd.h>
const char *bssid_to_string(const uint8_t bssid[BSSID_LENGTH], char bssid_string[BSSID_STRING_LENGTH])
{
snprintf(bssid_string, BSSID_STRING_LENGTH, "%02x:%02x:%02x:%02x:%02x:%02x",
bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
printf("%x\n", bssid[5]);
return bssid_string;
}
int main(int argc, char **argv){
struct wifi_scan *wifi=NULL;
struct station_info station;
char mac[BSSID_STRING_LENGTH];
wifi=wifi_scan_init(argv[1]);
wifi_scan_station(wifi, &station);
printf("ssid = %s mac = %s \n", station.ssid, bssid_to_string(station.bssid, mac));
wifi_scan_close(wifi);
}

Related

How to color output in C for cross-platform app

I am new and I know how to color output only in Unix/Linux systems:
#include <stdio.h>
int main(void) {
printf("\033[1;31mRed Message\033[0m.");
}
But this is not works in Windows cmd.exe, only in Unix terminal.
I am writing cross-platform app and want to know how can I do this in Windows cmd.exe too.
This also does not works:
1.
#include <stdio.h>
int main(void) {
printf("%c[1;31mRed Message%c[0m", 27, 27);
}
2.
#include <stdio.h>
int main(void) {
printf("[1;31m Red Message [0m");
}
This works, but I think this is just a bug:
If I type system(""); before printf then it works.
#include <stdio.h>
int main(void) {
system("");
printf("\033[1;31m Red Message \033[0m");
}
Thanks
If you want to make your library crossplatform, I would use the following approach:
Have a library, with the same functions, let's say:
void printInRed(const char* string). (In a headerfile)
After that you write two or more implementations.
One for windows:
//TODO: Errorchecking
void printInRed(const char* string){
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
//TODO: Extract magic number
//See https://stackoverflow.com/a/4053879/13912132
SetConsoleTextAttribute(hConsole, 12);
puts(string);
}
And another one for unix-like OS:
//TODO: Errorchecking
void printInRed(const char* string){
printf("\033[1;31m%s\033[0m.", string);
}
Then you can check at compile time, which version to compile.
The first approach is to use #ifdefs, but this will make the code a bit messy.
Another approach would be to use a build-system like CMake to select at build time, which one to build. A buildsystem requires a bit of learning, but will help you to make maintaining a crossplatform library simpler.

global static variable not changeable within a function? (gcc-89, uclinux)

I hope this is no duplicate but I had no idea what to search for. I have a strange behavieour with a c program and a static variable.
About the program: I am configuring a serial port and change the serial file descriptor in a configure_tty(int *fd_ptr) function.The program is an application for an embedded linux running microblaze uclinux. I am programming and cross compiling under Ubuntu 14.
I stripped it down to the following example:
#include <stdio.h>
static int fd;
static void config_tty(int *fd_ptr);
static void config_tty(int *fd_ptr){
int desc = 5; // here was open(serial port)
*fd_ptr = desc;
}
void main(){
printf("before: %i\n", fd);
config_tty(&fd);
printf("after: %i\n", fd);
}
This gives me `before: 0` and then `after: 5` what is what I expected.
I have to mention that my original program is cross-compiled with gcc -89 parameter and the compiler for microblaze uclinux.
I found the problem thanks to gdbserver and gdb over TCP. Within the config_tty everything is fine but right after *fd_ptr = desc; fd didn't change.
So I tried different things and now comes my question:
Changing static int fd; to int fd; fixed it.
Can anyone tell me what is the reason for this and why it is no problem in my example on Codelite for Windows? Is it compiler-specific?

Getting directory of binary in C

How do I get the absolute path to the directory of the currently executing command in C? I'm looking for something similar to the command dirname "$(readlink -f "$0")" in a shell script. For instance, if the C binary is /home/august/foo/bar and it's executed as foo/bar I want to get the result /home/august/foo.
Maybe try POSIX realpath() with argv[0]; something like the following (works on my machine):
#include <limits.h> /* PATH_MAX */
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
char buf[PATH_MAX];
char *res = realpath(argv[0], buf);
(void)argc; /* make compiler happy */
if (res) {
printf("Binary is at %s.\n", buf);
} else {
perror("realpath");
exit(EXIT_FAILURE);
}
return 0;
}
One alternative to argv[0] and realpath(3) on Linux is to use /proc/self/exe, which is a symbolic link pointing to the executable. You can use readlink(2) to get the pathname from it. See proc(5) for more information.
argv[0] is allowed to be NULL by the way (though this usually wouldn't happen in practice). It is also not guaranteed to contain the path used to run the command, though it will when starting programs from the shell.
I have come to the conclusion that there is no portable way for a commpiled executable to get the path to its directory. The obvious alternative is to pass an environment variable to the executable telling it where it is located.

Get Linux system information in C

I have to check Linux system information. I can execute system commands in C, but doing so I create a new process for every one, which is pretty expensive. I was wondering if there is a way to obtain system information without being forced to execute a shell command. I've been looking around for a while and I found nothing. Actually, I'm not even sure if it's more convenient to execute commands via Bash calling them from my C program or find a way to accomplish the tasks using only C.
Linux exposes a lot of information under /proc. You can read the data from there. For example, fopen the file at /proc/cpuinfo and read its contents.
A presumably less known (and more complicated) way to do that, is that you can also use the api interface to sysctl. To use it under Linux, you need to #include <unistd.h>, #include <linux/sysctl.h>. A code example of that is available in the man page:
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <linux/sysctl.h>
int _sysctl(struct __sysctl_args *args );
#define OSNAMESZ 100
int
main(void)
{
struct __sysctl_args args;
char osname[OSNAMESZ];
size_t osnamelth;
int name[] = { CTL_KERN, KERN_OSTYPE };
memset(&args, 0, sizeof(struct __sysctl_args));
args.name = name;
args.nlen = sizeof(name)/sizeof(name[0]);
args.oldval = osname;
args.oldlenp = &osnamelth;
osnamelth = sizeof(osname);
if (syscall(SYS__sysctl, &args) == -1) {
perror("_sysctl");
exit(EXIT_FAILURE);
}
printf("This machine is running %*s\n", osnamelth, osname);
exit(EXIT_SUCCESS);
}
However, the man page linked also notes:
Glibc does not provide a wrapper for this system call; call it using
syscall(2). Or rather... don't call it: use of this system call has
long been discouraged, and it is so unloved that it is likely to
disappear in a future kernel version. Since Linux 2.6.24, uses of this
system call result in warnings in the kernel log. Remove it from your
programs now; use the /proc/sys interface instead.
This system call is available only if the kernel was configured with
the CONFIG_SYSCTL_SYSCALL option.
Please keep in mind that anything you can do with sysctl(), you can also just read() from /proc/sys. Also note that I do understand that the usefulness of that syscall is questionable, I just put it here for reference.
You can also use the sys/utsname.h header file to get the kernel version, hostname, operating system, machine hardware name, etc. More about sys/utsname.h is here. This is an example of getting the current kernel release.
#include <stdio.h> // I/O
#include <sys/utsname.h>
int main(int argc, char const *argv[])
{
struct utsname buff;
printf("Kernel Release = %s\n", buff.release); // kernel release
return 0;
}
This is the same as using the uname command. You can also use the -a option which stands for all information.
uname -r # -r stands for kernel release

How can a C program determine and print the location of its own executable?

I want to write a a C program that prints its location.
For example if i put the program exe file to D:\myfolder\myc_prog, it should print the same location D:\myfolder\myc_prog and if I put that exe file to the location E:\mynewfold\ , it should print the updated location E:\mynewfold.
Actually, I have no idea how to do it that's why I'm not able to provide much details for this question.
Since you're using Windows, GetModuleFileName should do the trick. Just pass NULL for the hModule parameter. Be sure to read the documentation carefully if you want to handle long file names (and you typically do). You'll also have to strip the name of the executable to get the directory path. A quick-and-dirty way to do so is to remove everything after the last \.
#include <Windows.h>
#include <stdio.h>
int main(int argc, char *argv[]){
char buff[256];
if(GetCurrentDirectory(256, buff)){//get current directory
printf("%s\n", buff);
}
return 0;
}

Resources