/* Snownews - A lightweight console RSS newsreader * $Id: main.c 895 2005-03-18 12:20:14Z kiza $ * * Copyright 2003-2004 Oliver Feiler * http://kiza.kcore.de/software/snownews/ * * main.c * * Please read the file README.patching before changing any code in this file! * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #include "interface.h" #include "ui-support.h" #include "main.h" #include "updatecheck.h" #include "setup.h" #include "io-internal.h" #include "getopt.h" extern struct feed *first_bak; /* For use with the signal handler. */ static int const pid_file_create = 1; static int const pid_file_delete = 0; static int last_signal = 0; void modifyPIDFile (int action) { char pid_path[512]; FILE *file; snprintf(pid_path, sizeof(pid_path), "%s/.snownews/pid", getenv("HOME")); if (action == pid_file_create) { file = fopen(pid_path, "w"); if (file == NULL) { printf("Unable to write PID file %s!", pid_path); return; } fprintf(file, "%d", getpid()); fclose(file); } else { unlink(pid_path); } } /* Deinit ncurses and quit. */ void MainQuit (char * func, char * error) { if (error == NULL) { /* Only save settings if we didn't exit on error. */ WriteCache(); } clear(); refresh(); endwin(); /* Make sure no ncurses function is called after this point! */ modifyPIDFile(pid_file_delete); if (last_signal) printf ("Exiting via signal %d.\n", last_signal); if (error == NULL) { printf (_("Bye.\n\n")); /* Do this after everything else. If it doesn't work or hang user can ctrl-c without interfering with the program operation (like writing caches). */ AutoVersionCheck(); exit(0); } else { printf (_("Aborting program execution!\nAn internal error occured. Snownews has quit, no changes has been saved!\n")); printf (_("This shouldn't happen, please submit a bugreport to kiza@kcore.de, tell me what you where doing and include the output below in your mail.\n")); printf ("----\n"); /* Please don't localize! I don't want to receive Japanese error messages. * Thanks. :) */ printf ("While executing: %s\n", func); printf ("Error as reported by the system: %s\n\n", error); exit(1); } } /* Signal handler function. */ void MainSignalHandler (int sig) { last_signal = sig; /* If there is a first_bak!=NULL a filter is set. Reset first_ptr so the correct list gets written on the disk when exisiting via SIGINT. */ if (first_bak != NULL) first_ptr = first_bak; MainQuit(NULL, NULL); } /* Automatic child reaper. */ void sigChildHandler (int sig) { int status, child_val; /* Wait for any child without blocking */ if (waitpid(-1, &status, WNOHANG) < 0) return; if (WIFEXITED(status)) child_val = WEXITSTATUS(status); } int main (int argc, char *argv[]) { int autoupdate = 0; /* Automatically update feeds on app start... or not if set to 0. */ int numfeeds; /* Number of feeds loaded from Config(). */ #ifdef LOCALEPATH setlocale (LC_ALL, ""); bindtextdomain ("snownews", LOCALEPATH); textdomain ("snownews"); #endif /* Kiza's really sucky argument checker. Hey, it worked for Tornado. */ if (argc > 1) { if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0) { printf (_("Snownews version %s\n\n"), VERSION); return 0; } else if (strcmp(argv[1], "--update") == 0 || strcmp(argv[1], "-u") == 0) { autoupdate = 1; } else if (strcmp(argv[1], "--disable-versioncheck") == 0) { printf ("The option \"--disable-versioncheck\" has been obsoleted.\n"); printf ("Please see the manpage for details.\n"); printf ("(To deactivate check, put -1 into ~/.snownews/updatecheck)\n"); exit(1); } else { printf (_("Snownews version %s\n\n"), VERSION); printf (_("usage: snownews [-huV] [--help|--update|--version]\n\n")); printf (_("\t--update|-u\tAutomatically update every feed.\n")); printf (_("\t--help|-h\tPrint this help message.\n")); printf (_("\t--version|-V\tPrint version number and exit.\n")); printf (_("\t--disable-versioncheck (obsoleted)\n")); return 0; } } /* Get fragged gracefully. */ signal (SIGHUP, MainSignalHandler); signal (SIGINT, MainSignalHandler); signal (SIGTERM, MainSignalHandler); /* Un-broken pipify */ signal (SIGPIPE, SIG_IGN); /* Call the reaper */ signal (SIGCHLD, sigChildHandler); InitCurses(); /* Check if configfiles exist and create/read them. */ numfeeds = Config(); /* Create PID file. */ modifyPIDFile(pid_file_create); LoadAllFeeds (numfeeds); if (autoupdate) UpdateAllFeeds(); /* Init the pRNG. See about.c for usages of rand() ;) */ srand(time(0)); /* Give control to main program loop. */ UIMainInterface(); /* We really shouldn't be here at all... ah well. */ MainQuit(NULL, NULL); return 0; }