summaryrefslogtreecommitdiffstats
path: root/lanbrowsing/lisa/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lanbrowsing/lisa/main.cpp')
-rw-r--r--lanbrowsing/lisa/main.cpp290
1 files changed, 290 insertions, 0 deletions
diff --git a/lanbrowsing/lisa/main.cpp b/lanbrowsing/lisa/main.cpp
new file mode 100644
index 00000000..7de59389
--- /dev/null
+++ b/lanbrowsing/lisa/main.cpp
@@ -0,0 +1,290 @@
+/* main.cpp
+ *
+ * Copyright (c) 1998-2000 Alexander Neundorf
+ * neundorf@kde.org
+ *
+ * You may distribute under the terms of the GNU General Public
+ * License as specified in the COPYING file.
+ *
+ * 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.
+ *
+ */
+
+#include "lisadefines.h"
+#include "netmanager.h"
+
+#ifdef LISA_DEBUG
+#undef LISA_DEBUG
+#endif
+
+#ifdef dcerr
+#undef dcerr
+#endif
+
+#define LISA_DEBUG 0
+#define dcerr if (LISA_DEBUG==1) std::cerr<<"main "
+
+#include <iostream>
+#include <signal.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+// detect linux/glibc for the gnu style --args
+#if defined(__linux__) || defined(__linux) || defined(linux)
+# include <features.h>
+# ifdef __GLIBC__
+// only gnu libc has getopt.h... getopt(3) is defined to be in unistd.h
+// by POSIX.2
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+# include <getopt.h>
+# endif // __GLIBC__
+# define GNU_GETOPT
+#endif // linux
+
+
+void printVersion()
+{
+ const char * versionInfo=\
+ "\r\nThis is the LAN Information Server LISa "MYVERSION"\r\n"\
+ "It is free software according the GNU General Public License\r\n"\
+ "Copyright (c) 2000-2003 by Alexander Neundorf\r\n"\
+ "email: neundorf@kde.org\r\n";
+ std::cout<<versionInfo<<std::endl;
+}
+
+void usage()
+{
+ printVersion();
+ const char * usageInfo=\
+ "-v, --version prints out a short version info\n"\
+ "-u, --unix deprecated\n"\
+ "-k, --kde1 deprecated\n"\
+ "-K, --kde2 deprecated\n"\
+ " lisa now looks always first for $(HOME)/.lisarc, then for /etc/lisarc\n"\
+ "-c, --config=FILE read this and no other configuration file\n"\
+ "-q, --quiet start quiet without the greeting message\n"\
+ "-p, --port PORTNR start the server on this portnumber\n"\
+ " if you use this LISa won't be able to\n"\
+ " cooperate with other LISa's in the network\n"\
+ "-h, --help you are currently reading it ;-)\n";
+ std::cout<<usageInfo<<std::endl;
+//I thought this would be the way to check wether long options are supported...
+//#ifndef _GNU_SOURCE
+// std::cout<<"Please note that the long options are not supported on
+// this system"<<std::endl;
+//#endif
+}
+
+NetManager *manager(0);
+
+
+void destruct(int sigNumber)
+{
+ signal(sigNumber,SIG_IGN);
+ dcerr<<"signal caught: "<<sigNumber<<", exiting"<<std::endl;
+ //signal(sigNumber,&destruct);
+ if (manager!=0)
+ manager->~NetManager();
+ exit(0);
+}
+
+void readConfig(int sigNumber)
+{
+ dcerr<<"readConfig(): signal caught: "<<sigNumber<<std::endl;
+ signal(SIGHUP,SIG_IGN);
+ if (manager!=0)
+ manager->readConfig();
+ signal(SIGHUP,&readConfig);
+}
+
+void printState(int sigNumber)
+{
+ dcerr<<"printState(): signal caught: "<<sigNumber<<std::endl;
+ signal(SIGUSR1,SIG_IGN);
+ if (manager!=0)
+ manager->printState();
+ signal(SIGUSR1,&printState);
+}
+
+void setSignalHandler()
+{
+ signal(SIGHUP,&readConfig);
+ signal(SIGUSR1,&printState);
+
+ signal(SIGINT,&destruct);
+ signal(SIGQUIT,&destruct);
+ signal(SIGILL,&destruct);
+ signal(SIGTRAP,&destruct);
+ signal(SIGABRT,&destruct);
+ signal(SIGBUS,&destruct);
+ signal(SIGSEGV,&destruct);
+ signal(SIGUSR2,&destruct);
+ signal(SIGPIPE,&destruct);
+ signal(SIGALRM,&destruct);
+ signal(SIGTERM,&destruct);
+ signal(SIGFPE,&destruct);
+#ifdef SIGPOLL
+ signal(SIGPOLL, &destruct);
+#endif
+#ifdef SIGSYS
+ signal(SIGSYS, &destruct);
+#endif
+#ifdef SIGVTALRM
+ signal(SIGVTALRM, &destruct);
+#endif
+#ifdef SIGXCPU
+ signal(SIGXCPU, &destruct);
+#endif
+#ifdef SIGXFSZ
+ signal(SIGXFSZ, &destruct);
+#endif
+}
+
+#ifdef GNU_GETOPT
+static struct option const long_opts[] =
+{
+ {"version", no_argument, 0, 'v'},
+ {"quiet", no_argument, 0, 'q'},
+ {"unix", no_argument, 0, 'u'},
+ {"kde1", no_argument, 0, 'k'},
+ {"kde2", no_argument, 0, 'K'},
+ {"config", required_argument, 0, 'c'},
+ {"port", required_argument, 0, 'p'},
+ {"help", no_argument, 0, 'h'},
+ {0, 0, 0, 0}
+};
+#endif
+
+int main(int argc, char** argv)
+{
+ int quiet(0);
+ int c(0);
+ int configStyle(UNIXCONFIGSTYLE);
+ MyString configFile;
+ int portToUse(MYPORT);
+
+//I thought this would be the way to check wether long options are supported...
+#ifdef GNU_GETOPT
+ while ((c=getopt_long(argc, argv, "vqukKc:h", long_opts, 0))!=-1)
+#else
+ while ((c=getopt(argc, argv, "vqukKc:h"))!=-1)
+#endif
+
+ {
+ char *endp(0);
+ switch (c)
+ {
+ case 0:
+ break;
+ case 'v':
+ printVersion();
+ exit(0);
+ break;
+ case 'q':
+ quiet=1;
+ break;
+ case 'u':
+ case 'k':
+ case 'K':
+ std::cout<<"\a\nThe command line switches -k, -K, -u and \ntheir long versions "\
+ "--kde1, --kde2 and --unix are not supported anymore.\n"\
+ "Lisa will always first look for $(HOME)/.lisarc , then for /etc/lisarc.\n"\
+ "If your lisa configuration file was created using an older version of \n"\
+ "the KDE control center, copy the /root/.kde/share/config/lisarc to /etc and \n"\
+ "then start lisa without any command line options.\n"<<std::endl;
+ return 0;
+ break;
+
+ case 'c':
+ configFile = optarg;
+ configStyle = EXTRACONFIGSTYLE;
+ break;
+
+ case 'p':
+ portToUse=strtol(optarg,&endp,10);
+ if (endp!=0)
+ {
+ usage();
+ exit(0);
+ }
+ break;
+
+ case 'h':
+ default:
+ usage();
+ exit(0);
+ break;
+ }
+ }
+
+ //fork and let the parent exit
+ pid_t pid=fork();
+ if (pid>0)
+ {
+ //this is the parent
+ exit(0);
+ }
+ else if (pid<0)
+ {
+ std::cout<<"could not fork()"<<std::endl;
+ exit(0);
+ }
+ //we will only read/write to/from this socket in the child process
+ int rawSocket=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
+ if (rawSocket==-1)
+ {
+ std::cout<<"could not create raw socket, root privileges required"<<std::endl;
+ std::cout<<"take a look at the README for more information"<<std::endl;
+ exit(0);
+ }
+ int bufferSize(60*1024);
+ int on(1);
+ setsockopt(rawSocket, SOL_SOCKET, SO_RCVBUF, (char*)&bufferSize,
+ sizeof(bufferSize));
+ int result=setsockopt(rawSocket, SOL_SOCKET, SO_BROADCAST, (char*)&on,
+ sizeof(on));
+ dcerr<<"setsockopt returns "<<result<<std::endl;
+ //dropping root privileges
+ //they will be regained once in the child process
+ //for creating a raw socket
+
+ //now dropping root privileges once and ever
+
+
+ setuid(getuid());
+ if (geteuid() != getuid())
+ _exit(255);
+
+ //according to R. Stevens the following three lines
+ //make daemons feel good :)
+ setsid();
+ chdir("/");
+ umask(0);
+
+ dcerr<<"starting, dropped root privileges"<<std::endl;
+ dcerr<<"port: "<<portToUse<<" file: "<<configFile<<std::endl;
+ NetManager netmanager(rawSocket,portToUse,configFile,configStyle,0);
+ manager=&netmanager;
+ dcerr<<"NetManager created"<<std::endl;
+ setSignalHandler();
+
+ netmanager.readConfig();
+ if (netmanager.prepare())
+ {
+ if (!quiet)
+ {
+ printVersion();
+ std::cout<<"\n\rrunning on port "<<portToUse<<"\n\rHave fun ! :-)"<<std::endl;
+ }
+ netmanager.run();
+ };
+ dcerr<<"server finished"<<std::endl;
+}