#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include "fonts.h" #include "input_gadgets.h" #include "multiplexer.h" void drop_privileges(); void handle_signals(int signo); t_scroll_data scroll_data; int main(int argc, char **argv) { int ret_val; #define TEXT_BUFFER_LENGTH SCROLL_BUF_LEN / 5 char *text_buffer; char *text_buffer_end; // Set up gpi pointer for direct register access ret_val = multiplexer_setup_root(); if (ret_val) return ret_val; // Drop root privileges drop_privileges(); // set up / register signal handler struct sigaction new_action, old_action; new_action.sa_handler = handle_signals; sigemptyset (&new_action.sa_mask); new_action.sa_flags = 0; sigaction (SIGINT, NULL, &old_action); if (old_action.sa_handler != SIG_IGN) sigaction (SIGINT, &new_action, NULL); sigaction (SIGHUP, NULL, &old_action); if (old_action.sa_handler != SIG_IGN) sigaction (SIGHUP, &new_action, NULL); sigaction (SIGTERM, NULL, &old_action); if (old_action.sa_handler != SIG_IGN) sigaction (SIGTERM, &new_action, NULL); init_symbols_boundaries(); /************************************************************************\ * You are about to change the GPIO settings of your computer. * * Mess this up and it will stop working! * * It might be a good idea to 'sync' before running this program * * so at least you still have your code changes written to the SD-card! * \************************************************************************/ // configure the gpio pins and start the multiplexer thread multiplexer_setup_scroll(&scroll_data); text_buffer = malloc(TEXT_BUFFER_LENGTH); if (text_buffer == NULL) { fprintf(stderr, "malloc failed to allocate %d bytes\n", TEXT_BUFFER_LENGTH); turn_off_display(); return EXIT_FAILURE; } time_t next_update = 0; scroll_data . shine_until = time(NULL) + 10; int i=0; while (scroll_data . keep_running) { if (got_input()) { next_update = 0; // update now! scroll_data . shine_until = time(NULL) + 60; } if ((time(NULL) >= next_update) && (scroll_data . update == 0)) { next_update = time(NULL) + 600; // 10 minutes ahead memset(text_buffer, 0, TEXT_BUFFER_LENGTH); text_buffer_end = text_buffer; text_buffer_end = gadgets_retrieve_weather_warnings(text_buffer_end,text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end); if (text_buffer_end == NULL) { fprintf(stderr, "gadgets_retrieve_weather_warnings failed\n"); free(text_buffer); turn_off_display(); return EXIT_FAILURE; } if (text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end > 0) text_buffer_end += snprintf(text_buffer_end, text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end, "; "); text_buffer_end = gadgets_retrieve_current_temperature(text_buffer_end,text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end); if (text_buffer_end == NULL) { fprintf(stderr, "gadgets_retrieve_current_temperature failed\n"); free(text_buffer); turn_off_display(); return EXIT_FAILURE; } if (text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end > 0) text_buffer_end += snprintf(text_buffer_end, text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end, "; "); text_buffer_end = gadgets_retrieve_weather_forecast(text_buffer_end,text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end); if (text_buffer_end == NULL) { fprintf(stderr, "gadgets_retrieve_weather_forecast failed\n"); free(text_buffer); turn_off_display(); return EXIT_FAILURE; } if (text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end > 0) text_buffer_end += snprintf(text_buffer_end, text_buffer + TEXT_BUFFER_LENGTH - text_buffer_end, "; "); scroll_data . input_len = render( text_buffer, text_buffer_end - text_buffer, scroll_data . input, sizeof(scroll_data . input), 1 ); scroll_data . update = 1; } sleep(1); } free(text_buffer); pthread_join(scroll_data . thread_id, NULL); turn_off_display(); return EXIT_SUCCESS; } // main // // Drop (root) privileges // void drop_privileges() { /* Drop superuser privileges in correct order */ int is_already_unprivileged = 0; if (setgid(99) == -1) { perror("can't drop group privileges"); if (! (is_already_unprivileged = (errno == 1))) exit(-1); } if (setuid(99) == -1) { perror("can't drop user privileges"); if (is_already_unprivileged != (errno == 1)) exit(-1); } } // drop_root void handle_signals(int signo) { if ((signo == SIGINT) || (signo == SIGHUP) || (signo == SIGTERM)) { fprintf(stderr, "stopping\n"); scroll_data . keep_running = 0; } }