3 * Copyright (c) 1998-2000 Alexander Neundorf
6 * You may distribute under the terms of the GNU General Public
7 * License as specified in the COPYING file.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
16 #include "lisadefines.h"
17 #include "netmanager.h"
22 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
27 // detect linux/glibc for the gnu style --args
28 #if defined(__linux__) || defined(__linux) || defined(linux)
29 # include <features.h>
31 // only gnu libc has getopt.h... getopt(3) is defined to be in unistd.h
50 #define dcerr if (LISA_DEBUG==1) std::cerr<<"strictmain "
54 const char * versionInfo
=\
55 "\r\nThis is the restricted LAN Information Server resLISa "MYVERSION
"\r\n"\
56 "It is free software according the GNU General Public License\r\n"\
57 "Copyright (c) 2000-2003 by Alexander Neundorf\r\n"\
58 "email: neundorf@kde.org\r\n";
59 std::cout
<<versionInfo
<<std::endl
;
65 const char * usageInfo
=\
66 "-v, --version prints out a short version info\n"\
67 "-u, --unix deprecated\n"\
68 "-k, --kde1 deprecated\n"\
69 "-K, --kde2 deprecated\n"\
70 " reslisa now always looks first for $(HOME)/.reslisarc, then for /etc/reslisarc\"\n"\
71 "-c, --config=FILE read this and no other configuration file\n"\
72 "-q, --quiet start quiet without the greeting message\n"\
73 "-h, --help you are currently reading it ;-)\n";
74 std::cout
<<usageInfo
<<std::endl
;
75 //I thought this would be the way to check wether long options are supported...
77 // cout<<"Please note that the long options are not supported on this system"<<endl;
81 void destruct(int sigNumber
)
83 signal(sigNumber
,SIG_IGN
);
84 std::cout
<<"signal caught: "<<sigNumber
<<", exiting"<<std::endl
;
85 //signal(sigNumber,&destruct);
89 NetManager
*manager(0);
91 void readConfig(int sigNumber
)
93 std::cout
<<"readConfig(): signal caught: "<<sigNumber
<<std::endl
;
94 signal(SIGHUP
,SIG_IGN
);
96 manager
->readConfig();
97 signal(SIGHUP
,&readConfig
);
100 void printState(int sigNumber
)
102 std::cout
<<"printState(): signal caught: "<<sigNumber
<<std::endl
;
103 signal(SIGUSR1
,SIG_IGN
);
105 manager
->printState();
106 signal(SIGUSR1
,&printState
);
109 void setSignalHandler()
111 signal(SIGHUP
,&readConfig
);
112 signal(SIGUSR1
,&printState
);
114 signal(SIGINT
,&destruct
);
115 signal(SIGQUIT
,&destruct
);
116 signal(SIGILL
,&destruct
);
117 signal(SIGTRAP
,&destruct
);
118 signal(SIGABRT
,&destruct
);
119 signal(SIGBUS
,&destruct
);
120 signal(SIGSEGV
,&destruct
);
121 signal(SIGUSR2
,&destruct
);
122 signal(SIGPIPE
,&destruct
);
123 signal(SIGALRM
,&destruct
);
124 signal(SIGTERM
,&destruct
);
125 signal(SIGFPE
,&destruct
);
127 signal(SIGPOLL
, &destruct
);
130 signal(SIGSYS
, &destruct
);
133 signal(SIGVTALRM
, &destruct
);
136 signal(SIGXCPU
, &destruct
);
139 signal(SIGXFSZ
, &destruct
);
144 static struct option
const long_opts
[] =
146 {"version", no_argument
, 0, 'v'},
147 {"quiet", no_argument
, 0, 'q'},
148 {"unix", no_argument
, 0, 'u'},
149 {"kde1", no_argument
, 0, 'k'},
150 {"kde2", no_argument
, 0, 'K'},
151 {"config", required_argument
, 0, 'c'},
152 {"help", no_argument
, 0, 'h'},
157 int main(int argc
, char** argv
)
161 int configStyle(UNIXCONFIGSTYLE
);
163 int portToUse(MYPORT
);
165 //I thought this would be the way to check wether long options are supported...
167 while ((c
=getopt_long(argc
, argv
, "vqukKc:h", long_opts
, 0))!=-1)
169 while ((c
=getopt(argc
, argv
, "vqukKc:h"))!=-1)
186 std::cerr
<<"\a\nThe command line switches -k, -K, -u and \ntheir long versions "\
187 "--kde1, --kde2 and --unix are not supported anymore.\n"\
188 "ResLisa will always first look for $(HOME)/.reslisarc , then for /etc/reslisarc.\n"\
189 "If your lisa configuration file was created using an older version of \n"\
190 "the KDE control center, copy the $(HOME)/.kde/share/config/reslisarc to $(HOME)/.reslisarc.\n"<<std::endl
;
195 configStyle
= EXTRACONFIGSTYLE
;
206 //fork and let the parent exit
215 dcerr
<<"could not fork()"<<std::endl
;
218 //we will only read/write to/from this socket in the child process
219 int rawSocket
=socket(AF_INET
,SOCK_RAW
,IPPROTO_ICMP
);
222 std::cout
<<"could not create raw socket, root privileges required"<<std::endl
;
223 std::cout
<<"take a look at the README for more information"<<std::endl
;
226 int bufferSize(60*1024);
228 setsockopt(rawSocket
, SOL_SOCKET
, SO_RCVBUF
, (char*)&bufferSize
,
230 int result
=setsockopt(rawSocket
, SOL_SOCKET
, SO_BROADCAST
, (char*)&on
,
232 dcerr
<<"setsockopt returns "<<result
<<std::endl
;
233 //dropping root privileges
234 //they will be regained once in the child process
235 //for creating a raw socket
237 //now dropping root privileges once and ever
240 //according to R. Stevens the following three lines
241 //make daemons feel good :)
246 dcerr
<<"starting, dropped root privileges"<<std::endl
;
247 dcerr
<<"port: "<<portToUse
<<" file: "<<configFile
<<std::endl
;
248 NetManager
netmanager(rawSocket
,portToUse
,configFile
,configStyle
,1);
250 dcerr
<<"NetManager created"<<std::endl
;
253 netmanager
.readConfig();
254 if (netmanager
.prepare())
260 dcerr
<<"server finished"<<std::endl
;