Execute command just before Mac going to sleep - c

I wrote a C program/LaunchDaemon that checks if my MacBook is at home (connected to my WLAN). If so, it disables my password protection; if not, it enables it.
Easy. But the problem is that when I take my MacBook anywhere else and password protection is disabled, it will wake up without a password protection.
My fix for this would be: enable the password protection every time just before it goes to sleep.
QUESTION: is there any way find out when my Mac is preparing for sleep? Some interupt I can let my program listen to?

You can do it using I/O Kit, check Apple's QA1340: Registering and
unregistering for sleep and wake notifications. You may also want to
analyze the SleepWatcher utility sources or use/integrate for your needs.
From the homepage:
SleepWatcher 2.2 (running with Mac OS X 10.5 to 10.8, source code included)
is a command line tool (daemon) for Mac OS X that monitors sleep, wakeup and
idleness of a Mac. It can be used to execute a Unix command when the Mac or
the display of the Mac goes to sleep mode or wakes up, after a given time
without user interaction or when the user resumes activity after a break or
when the power supply of a Mac notebook is attached or detached. It also can
send the Mac to sleep mode or retrieve the time since last user activity. A
little bit knowledge of the Unix command line is required to benefit from
this software.

I attach below the contents of my C file beforesleep.c which executes some command line commands (in my case shell commands and AppleScript scripts) when a "will sleep" notification is received.
Where you can put your code:
In order to run your code when the mac is going to sleep, just replace the system(...) calls with the code you wish to run.
In my case, I use system() as it allows me to run shell commands passed as strings, but if you prefer to run just C code instead, you can just put your C code there.
How to build it
In order to build this file, I run:
gcc -framework IOKit -framework Cocoa beforesleep.c
Remark
If you are going to use this code, make sure it is always running in background. For example, I have a Cron job which makes sure that this code is always running, and it launches it again in case it is accidentally killed for any reason (although it never happened to me so far). If you are experienced enough, you can find smarter ways to ensure this.
Further info
See this link (already suggested by sidyll) for more details about how this works.
Code template
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <mach/mach_port.h>
#include <mach/mach_interface.h>
#include <mach/mach_init.h>
#include <IOKit/pwr_mgt/IOPMLib.h>
#include <IOKit/IOMessage.h>
io_connect_t root_port; // a reference to the Root Power Domain IOService
void
MySleepCallBack( void * refCon, io_service_t service, natural_t messageType, void * messageArgument )
{
switch ( messageType )
{
case kIOMessageCanSystemSleep:
IOAllowPowerChange( root_port, (long)messageArgument );
break;
case kIOMessageSystemWillSleep:
system("/Users/andrea/bin/mylogger.sh");
system("osascript /Users/andrea/bin/pause_clockwork.scpt");
IOAllowPowerChange( root_port, (long)messageArgument );
break;
case kIOMessageSystemWillPowerOn:
//System has started the wake up process...
break;
case kIOMessageSystemHasPoweredOn:
//System has finished waking up...
break;
default:
break;
}
}
int main( int argc, char **argv )
{
// notification port allocated by IORegisterForSystemPower
IONotificationPortRef notifyPortRef;
// notifier object, used to deregister later
io_object_t notifierObject;
// this parameter is passed to the callback
void* refCon;
// register to receive system sleep notifications
root_port = IORegisterForSystemPower( refCon, &notifyPortRef, MySleepCallBack, &notifierObject );
if ( root_port == 0 )
{
printf("IORegisterForSystemPower failed\n");
return 1;
}
// add the notification port to the application runloop
CFRunLoopAddSource( CFRunLoopGetCurrent(),
IONotificationPortGetRunLoopSource(notifyPortRef), kCFRunLoopCommonModes );
/* Start the run loop to receive sleep notifications. Don't call CFRunLoopRun if this code
is running on the main thread of a Cocoa or Carbon application. Cocoa and Carbon
manage the main thread's run loop for you as part of their event handling
mechanisms.
*/
CFRunLoopRun();
//Not reached, CFRunLoopRun doesn't return in this case.
return (0);
}

Related

Let a daemon simulate keypress with xdo

I'm trying to make a daemon simulate a keypress. I got it already working for a non daemon process.
#include <xdo.h>
int main()
{
xdo_t * x = xdo_new(NULL);
xdo_enter_text_window(x, CURRENTWINDOW, "Hallo xdo!", 500000);
return 0;
}
If I try the same code for my daemon I get the following error
Error: Can't open display: (null)
Is there a way to still make it work with xdo or something else?
Your process must know the $DESKTOP environment variable specifying the desktop session to send these keys to, and yours doesn't seem to have that environment set.
Which also means you must realize it needs to have all the necessary privileges, which means access to ~/.Xauthority of the owner of the session, and the sockets in /tmp/.X11-unix

How to make c programe as daemon in ubuntu?

Hi I am new to the linux environment. I am trying to create daemon process.
#include<stdio.h>
int main()
{
int a=10,b=10,c;
c=sum(a,b);
printf("%d",c);
return (0);
}
int sum(int a,int b)
{
return a+b;
}
I want to create daemon process of it. May i know how can do this? Any help would be appreciated. Thank you.
A daemon generally doesn't use its standard input and output streams, so it is unclear how your program could be run as a daemon. And a daemon program usually don't have any terminal, so it cannot use clrscr. Read also the tty demystified page, and also daemon(7).
I recommend reading some good introduction to Linux programming, like the old freely downloadable ALP (or something newer). We can't explain all of it here, and you need to read an entire book. See also intro(2) and syscalls(2).
I also recommend reading more about OSes, e.g. the freely available Operating Systems: Three Easy Pieces textbook.
You could use the daemon(3) function in your C program to run it as a daemon (but then, you are likely to not have any input and output). You may want to log messages using syslog(3).
You might consider job control facilities of your shell. You could run your program in the background (e.g. type myprog myarg & in your interactive shell). You could use the batch command. However neither background processes nor batch jobs are technically daemons.
Perhaps you want to code some ONC-RPC or JSONRPC or Web API server and client. You'll find libraries for that. See also pipe(7), socket(7)
(take several days or several weeks to read much more)
First find what are the properties of daemon process, as of my knowledge a daemon process have these properties:
Should not have any parent (it itself should be parent)
Process itself is a session leader.
Environment change to root.
File mode creating mask should be zero.
No controlling terminal.
All terminal should be removed
Should not be un-mounted .
Implement the code by considering above properties which is
int i=0;
int main()
{
int pid;
pid=fork();
if(pid!=0) {
/** you can add your task here , whatever you want to run in background **/
exit(0);
}
else
{
setsid();//setting sessions
chdir("/");//root.. should'nt beunmounted
umask(0);
close(0);//all terminal are removed
close(1);
close(2);
while(1)
{
printf("i = %d \n",i);
i++;
}
}
return 0;
}
or you can go through man page of daemon()
int daemon(int nochdir, int noclose);
I hope it helps.
Instead of writing the code to make the C program a daemon I would go with an already mature tool like supervisor:
http://supervisord.org/
I think this below will work
screen cmd arg1 arg2
You can also try
nohup cmd arg1

How can I have skinnier pthreads?

I have a really basic ncurses program to monitor machine statistics and launch remote xterms. It just sits on a window all day and helps me choose a not-heavily-loaded machine to work on. It works fine, and I love it dearly. But it's really fat. Much fatter than it needs to be, I think.
The program basically is as follows:
void * run(void * task) {
// once per minute:
popen( /* stats checking command */ )
// save output to global var
pclose
}
int main() {
// setup ncurses with halfdelay
for ( /* each machine */ )
pthread_create(somethread, NULL, run, (void *)somestruct);
while ( ( c = getch() ) != 'q' )
for ( /* each machine */ )
// print machine stats
// maybe launch an xterm
// die gracefully
}
And as stated above, it works just fine. The problem is that each thread has all the ncurses baloney tucked in private memory leading to one very fat process with a boatload of wasted bits.
The question, then, is this: how can I re-write or re-arrange this program so that each pthread doesn't carry around all the unnecessary ncurses stuff?
Side-question: You'll have to really sell me on it, but does anyone know of a better method than ncurses to do this? I want the stats on fixed positions in the terminal window, not scrolling text.

How to debug cgi program written in C and running in Apache2?

I have a complex cgi executable written in C, I configured in Apache2 and now it is running succesfully. How can I debug this program in the source code, such as set break points and inspect variables? Any tools like gdb or eclipse? Any tutorial of how to set up the debugging environment?
Thanks in advance!!
The CGI interface basically consists in passing the HTTP request to the executable's standard input and getting the response on the standard output. Therefore you can write test requests to files and manually execute your CGI without having to use Apache. The debugging can then be done with GDB :
gdb ./my_cgi
>> break some_func
>> run < my_req.txt
with my_req.txt containing the full request:
GET /some/func HTTP/1.0
Host: myhost
If you absolutely need the CGI to be run by Apache it may become tricky to attach GDB to the right process. You can for example configure Apache to have only one worker process, attach to it with gdb -p and use set follow-fork-mode child to make sure it switches to the CGI process when a request arrives.
I did this: in cgi main i added code to look for an existing file, like /var/tmp/flag. While existing, i run in a loop. Time enough to attach to cgi process via gdb. After then i delete /var/tmp/flag and from now I can debug my cgi code.
bool file_exists(const char *filename)
{
ifstream ifile(filename);
return ifile;
}
int cgiMain()
{
while (file_exists ("/var/tmp/flag"))
sleep (1);
...
your code
Unless FastCGI or SCGI is used, the CGI process is short-lived and you need to delay its exit to have enough time to attach the debugger while the process is still running. For casual debugging the easiest option is to simply use sleep() in an endless loop at the breakpoint location and exit the loop with the debugger once it is attached to the program.
Here's a small example CGI program:
#include <stdio.h>
#include <unistd.h>
void wait_for_gdb_to_attach() {
int is_waiting = 1;
while (is_waiting) {
sleep(1); // sleep for 1 second
}
}
int main(void) {
wait_for_gdb_to_attach();
printf("Content-Type: text/plain;charset=us-ascii\n\n");
printf("Hello!");
return 0;
}
Suppose it is compiled into cgi-debugging-example, this is how you would attach the debugger once the application enters the endless loop:
sudo cgdb cgi-debugging-example $(pgrep cgi-debugging)
Next you need to exit the infinite loop and wait_for_gdb_to_attach() function to reach the "breakpoint" in your application. The trick here is to step out of sleep functions until you reach wait_for_gdb_to_attach() and set the value of the variable is_waiting with the debugger so that while (is_waiting) exits:
(gdb) finish
Run till exit from 0x8a0920 __nanosleep_nocancel () at syscall-template.S:81
0x8a07d4 in __sleep (seconds=0) at sleep.c:137
(gdb) finish
Run till exit from 0x8a07d4 in __sleep (seconds=0) at sleep.c:137
wait_for_gdb_to_attach () at cgi-debugging-example.c:6
Value returned is $1 = 0
(gdb) set is_waiting = 0 # <<<<<< to exit while
(gdb) finish
Run till exit from wait_for_gdb_to_attach () cgi-debugging-example.c:6
main () at cgi-debugging-example.c:13
Once you are out of wait_for_gdb_to_attach(), you can continue debugging the program or let it run to completion.
Full example with detailed instructions here.
I'm not sure how to use gdb or other frontends in eclipse, but I just debugged my CGI program with gdb. I'd like to share something that other answers didn't mention, that CGIs usually need to read request meta-variables defined in RFC 3875#4.1 with getenv(3). Popular request variables in my mind are:
SCRIPT_NAME
QUERY_STRING
CONTENT_LENGTH
CONTENT_TYPE
REMOTE_ADDR
There variables are provided by http servers such as Apache. When debugging with gdb, we need to set these values by our own with set environment. In my case, there're only a few variables neededa(and the source code is very old, it still uses SCRIPT_URL instead of SCRIPT_NAME), so here's my example:
gdb cgi_name
set environment SCRIPT_URL /path/to/sub/cgis
set environment QUERY_STRING p1=v1&p2=v2
break foo.c:42
run
For me both solutions for debugging the CGI in gdb without web server presented above didn't work.
Maybe the second solution works for a GET Request.
I needed a combination of both, first setting the environment variables from rfc3875 (not sure if all of them are really neded).
Then I was able to pass only the params (not the compltete request) via STDIN from a file.
gdb cgi_name
set environment REQUEST_METHOD=POST
set environment CONTENT_LENGTH=1337
set environment CONTENT_TYPE=application/json
set environment SCRIPT_NAME=my.cgi
set environment REMOTE_ADDR=127.0.0.1
run < ./params.txt
With params.txt:
{"user":"admin","pass":"admin"}

Set wireless channel using netlink API

I am developing a WiFi tool in Ubuntu Linux 12.04 environment and I need to switch the WiFi interface between different channels.
Currently I found the solution in Wireshark source code ws80211_utils.c in function called ws80211_set_freq but I do not know how to implement it into my source code and which libs to include and how to compile so I could test it.
The problem is that there are too many arguments and flags you have to use. Also, this is the first time I develop a netlink wifi tool.
If there are any good manuals available where to start and how to use netlink calls for WiFi please provide me with the link.
Thanks a lot i advance!
In current Linux versions, nl80211 is the right way to "talk" to the wireless subsystem. Be aware that you cannot arbitrarily set a channel with every driver and every operating mode (master, client, monitor etc.) Some drivers allow a channel change only when the corresponding interface is "down". In modes such as client ("managed"), the channel cannot be set at all because it is defined by the access point.
Also note that not all wireless device drivers use mac80211/cfg80211. For those drivers not using it, you either have to use the old wireless extensions API or (even worse) a driver-specific proprietary API.
Sadly, there seems to be no up-to-date and complete documentation of the nl80211 interface. Please correct me if I am wrong!
Your approach of looking into the source code of other programs seems to be a reasonable way. You could also use the source code of the iw command line utility. iw has an option to set the channel:
$ iw --help
Usage: iw [options] command
Options:
--debug enable netlink debugging
--version show version (3.2)
Commands:
…
dev <devname> set channel <channel> [HT20|HT40+|HT40-]
…
In iw's phy.c, line 91ff. you can find the code called when iw wlan0 set channel is executed. However, this code is definitely not easy to read. It looks like the
NL80211_CMD_SET_WIPHYcommand in conjunction with the NL80211_ATTR_WIPHY_FREQ attribute is the way to go.
In this SO answer you can find a skeleton program for using nl80211. Also, the code of Aircrack-ng (src/osdep/linux.c, function linux_set_channel_nl80211) could act as a blueprint.
The accepted answer is currently correct, but there's no example code posted yet which solves the OP's question (even if nearly 4 years late), so I thought I would add this here for any future search engine users. It's adapted from this SO question and the specific Aircrack-ng file (/src/aircrack-osdep/linux.c, line 1050) that were both previously mentioned.
#include <net/if.h>
#include <netlink/netlink.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
#include <linux/nl80211.h>
int main(int argc, char *argv[])
{
/* The device's name and the frequency we wish to set it to. */
char *device = "wlan1";
int frequencyMhz = 2442;
/* Create the socket and connect to it. */
struct nl_sock *sckt = nl_socket_alloc();
genl_connect(sckt);
/* Allocate a new message. */
struct nl_msg *mesg = nlmsg_alloc();
/* Check /usr/include/linux/nl80211.h for a list of commands and attributes. */
enum nl80211_commands command = NL80211_CMD_SET_WIPHY;
/* Create the message so it will send a command to the nl80211 interface. */
genlmsg_put(mesg, 0, 0, genl_ctrl_resolve(sckt, "nl80211"), 0, 0, command, 0);
/* Add specific attributes to change the frequency of the device. */
NLA_PUT_U32(mesg, NL80211_ATTR_IFINDEX, if_nametoindex(device));
NLA_PUT_U32(mesg, NL80211_ATTR_WIPHY_FREQ, frequencyMhz);
/* Finally send it and receive the amount of bytes sent. */
int ret = nl_send_auto_complete(sckt, mesg);
printf("%d Bytes Sent\n", ret);
nlmsg_free(mesg);
return EXIT_SUCCESS;
nla_put_failure:
nlmsg_free(mesg);
printf("PUT Failure\n");
return EXIT_FAILURE;
}
Compile this with gcc main.c $(pkg-config --cflags --libs libnl-3.0 libnl-genl-3.0).
Once executed, check the frequency/channel of your device with e.g. iw wlan1 info or iwconfig. There's no serious error checking here, so all you will notice is if the message was sent or not. Hopefully this helps anyone like me making the transition from Wireless Extensions to cfg80211 and nl80211.

Resources