* fix crash in PersonalInviteDialog
[kdenetwork.git] / lanbrowsing / lisa / main.cpp
blob7de593890dc5b6317424b20ab4994e98d49fcc57
1 /* main.cpp
3 * Copyright (c) 1998-2000 Alexander Neundorf
4 * neundorf@kde.org
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"
19 #ifdef LISA_DEBUG
20 #undef LISA_DEBUG
21 #endif
23 #ifdef dcerr
24 #undef dcerr
25 #endif
27 #define LISA_DEBUG 0
28 #define dcerr if (LISA_DEBUG==1) std::cerr<<"main "
30 #include <iostream>
31 #include <signal.h>
32 #include <unistd.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <sys/socket.h>
36 #include <netinet/in.h>
38 // detect linux/glibc for the gnu style --args
39 #if defined(__linux__) || defined(__linux) || defined(linux)
40 # include <features.h>
41 # ifdef __GLIBC__
42 // only gnu libc has getopt.h... getopt(3) is defined to be in unistd.h
43 // by POSIX.2
44 #ifndef _GNU_SOURCE
45 # define _GNU_SOURCE
46 #endif
47 # include <getopt.h>
48 # endif // __GLIBC__
49 # define GNU_GETOPT
50 #endif // linux
53 void printVersion()
55 const char * versionInfo=\
56 "\r\nThis is the LAN Information Server LISa "MYVERSION"\r\n"\
57 "It is free software according the GNU General Public License\r\n"\
58 "Copyright (c) 2000-2003 by Alexander Neundorf\r\n"\
59 "email: neundorf@kde.org\r\n";
60 std::cout<<versionInfo<<std::endl;
63 void usage()
65 printVersion();
66 const char * usageInfo=\
67 "-v, --version prints out a short version info\n"\
68 "-u, --unix deprecated\n"\
69 "-k, --kde1 deprecated\n"\
70 "-K, --kde2 deprecated\n"\
71 " lisa now looks always first for $(HOME)/.lisarc, then for /etc/lisarc\n"\
72 "-c, --config=FILE read this and no other configuration file\n"\
73 "-q, --quiet start quiet without the greeting message\n"\
74 "-p, --port PORTNR start the server on this portnumber\n"\
75 " if you use this LISa won't be able to\n"\
76 " cooperate with other LISa's in the network\n"\
77 "-h, --help you are currently reading it ;-)\n";
78 std::cout<<usageInfo<<std::endl;
79 //I thought this would be the way to check wether long options are supported...
80 //#ifndef _GNU_SOURCE
81 // std::cout<<"Please note that the long options are not supported on
82 // this system"<<std::endl;
83 //#endif
86 NetManager *manager(0);
89 void destruct(int sigNumber)
91 signal(sigNumber,SIG_IGN);
92 dcerr<<"signal caught: "<<sigNumber<<", exiting"<<std::endl;
93 //signal(sigNumber,&destruct);
94 if (manager!=0)
95 manager->~NetManager();
96 exit(0);
99 void readConfig(int sigNumber)
101 dcerr<<"readConfig(): signal caught: "<<sigNumber<<std::endl;
102 signal(SIGHUP,SIG_IGN);
103 if (manager!=0)
104 manager->readConfig();
105 signal(SIGHUP,&readConfig);
108 void printState(int sigNumber)
110 dcerr<<"printState(): signal caught: "<<sigNumber<<std::endl;
111 signal(SIGUSR1,SIG_IGN);
112 if (manager!=0)
113 manager->printState();
114 signal(SIGUSR1,&printState);
117 void setSignalHandler()
119 signal(SIGHUP,&readConfig);
120 signal(SIGUSR1,&printState);
122 signal(SIGINT,&destruct);
123 signal(SIGQUIT,&destruct);
124 signal(SIGILL,&destruct);
125 signal(SIGTRAP,&destruct);
126 signal(SIGABRT,&destruct);
127 signal(SIGBUS,&destruct);
128 signal(SIGSEGV,&destruct);
129 signal(SIGUSR2,&destruct);
130 signal(SIGPIPE,&destruct);
131 signal(SIGALRM,&destruct);
132 signal(SIGTERM,&destruct);
133 signal(SIGFPE,&destruct);
134 #ifdef SIGPOLL
135 signal(SIGPOLL, &destruct);
136 #endif
137 #ifdef SIGSYS
138 signal(SIGSYS, &destruct);
139 #endif
140 #ifdef SIGVTALRM
141 signal(SIGVTALRM, &destruct);
142 #endif
143 #ifdef SIGXCPU
144 signal(SIGXCPU, &destruct);
145 #endif
146 #ifdef SIGXFSZ
147 signal(SIGXFSZ, &destruct);
148 #endif
151 #ifdef GNU_GETOPT
152 static struct option const long_opts[] =
154 {"version", no_argument, 0, 'v'},
155 {"quiet", no_argument, 0, 'q'},
156 {"unix", no_argument, 0, 'u'},
157 {"kde1", no_argument, 0, 'k'},
158 {"kde2", no_argument, 0, 'K'},
159 {"config", required_argument, 0, 'c'},
160 {"port", required_argument, 0, 'p'},
161 {"help", no_argument, 0, 'h'},
162 {0, 0, 0, 0}
164 #endif
166 int main(int argc, char** argv)
168 int quiet(0);
169 int c(0);
170 int configStyle(UNIXCONFIGSTYLE);
171 MyString configFile;
172 int portToUse(MYPORT);
174 //I thought this would be the way to check wether long options are supported...
175 #ifdef GNU_GETOPT
176 while ((c=getopt_long(argc, argv, "vqukKc:h", long_opts, 0))!=-1)
177 #else
178 while ((c=getopt(argc, argv, "vqukKc:h"))!=-1)
179 #endif
182 char *endp(0);
183 switch (c)
185 case 0:
186 break;
187 case 'v':
188 printVersion();
189 exit(0);
190 break;
191 case 'q':
192 quiet=1;
193 break;
194 case 'u':
195 case 'k':
196 case 'K':
197 std::cout<<"\a\nThe command line switches -k, -K, -u and \ntheir long versions "\
198 "--kde1, --kde2 and --unix are not supported anymore.\n"\
199 "Lisa will always first look for $(HOME)/.lisarc , then for /etc/lisarc.\n"\
200 "If your lisa configuration file was created using an older version of \n"\
201 "the KDE control center, copy the /root/.kde/share/config/lisarc to /etc and \n"\
202 "then start lisa without any command line options.\n"<<std::endl;
203 return 0;
204 break;
206 case 'c':
207 configFile = optarg;
208 configStyle = EXTRACONFIGSTYLE;
209 break;
211 case 'p':
212 portToUse=strtol(optarg,&endp,10);
213 if (endp!=0)
215 usage();
216 exit(0);
218 break;
220 case 'h':
221 default:
222 usage();
223 exit(0);
224 break;
228 //fork and let the parent exit
229 pid_t pid=fork();
230 if (pid>0)
232 //this is the parent
233 exit(0);
235 else if (pid<0)
237 std::cout<<"could not fork()"<<std::endl;
238 exit(0);
240 //we will only read/write to/from this socket in the child process
241 int rawSocket=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
242 if (rawSocket==-1)
244 std::cout<<"could not create raw socket, root privileges required"<<std::endl;
245 std::cout<<"take a look at the README for more information"<<std::endl;
246 exit(0);
248 int bufferSize(60*1024);
249 int on(1);
250 setsockopt(rawSocket, SOL_SOCKET, SO_RCVBUF, (char*)&bufferSize,
251 sizeof(bufferSize));
252 int result=setsockopt(rawSocket, SOL_SOCKET, SO_BROADCAST, (char*)&on,
253 sizeof(on));
254 dcerr<<"setsockopt returns "<<result<<std::endl;
255 //dropping root privileges
256 //they will be regained once in the child process
257 //for creating a raw socket
259 //now dropping root privileges once and ever
262 setuid(getuid());
263 if (geteuid() != getuid())
264 _exit(255);
266 //according to R. Stevens the following three lines
267 //make daemons feel good :)
268 setsid();
269 chdir("/");
270 umask(0);
272 dcerr<<"starting, dropped root privileges"<<std::endl;
273 dcerr<<"port: "<<portToUse<<" file: "<<configFile<<std::endl;
274 NetManager netmanager(rawSocket,portToUse,configFile,configStyle,0);
275 manager=&netmanager;
276 dcerr<<"NetManager created"<<std::endl;
277 setSignalHandler();
279 netmanager.readConfig();
280 if (netmanager.prepare())
282 if (!quiet)
284 printVersion();
285 std::cout<<"\n\rrunning on port "<<portToUse<<"\n\rHave fun ! :-)"<<std::endl;
287 netmanager.run();
289 dcerr<<"server finished"<<std::endl;