Add feature 85117: [liboscar/icq] password changing support for ICQ.
[kdenetwork.git] / lanbrowsing / lisa / strictmain.cpp
bloba948d6df32c3c4bcff77b2ad56d58f4d1ff8b5f6
1 /* strictmain.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 #include <iostream>
20 #include <signal.h>
21 #include <unistd.h>
22 #include <sys/types.h>
23 #include <sys/stat.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>
30 # ifdef __GLIBC__
31 // only gnu libc has getopt.h... getopt(3) is defined to be in unistd.h
32 // by POSIX.2
33 # ifndef _GNU_SOURCE
34 # define _GNU_SOURCE
35 # endif
36 # include <getopt.h>
37 # endif // __GLIBC__
38 # define GNU_GETOPT
39 #endif // linux
41 #ifdef LISA_DEBUG
42 #undef LISA_DEBUG
43 #endif
44 #define LISA_DEBUG 0
46 #ifdef dcerr
47 #undef dcerr
48 #endif
50 #define dcerr if (LISA_DEBUG==1) std::cerr<<"strictmain "
52 void printVersion()
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;
62 void usage()
64 printVersion();
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...
76 //#ifndef _GNU_SOURCE
77 // cout<<"Please note that the long options are not supported on this system"<<endl;
78 //#endif
81 void destruct(int sigNumber)
83 signal(sigNumber,SIG_IGN);
84 std::cout<<"signal caught: "<<sigNumber<<", exiting"<<std::endl;
85 //signal(sigNumber,&destruct);
86 exit(0);
89 NetManager *manager(0);
91 void readConfig(int sigNumber)
93 std::cout<<"readConfig(): signal caught: "<<sigNumber<<std::endl;
94 signal(SIGHUP,SIG_IGN);
95 if (manager!=0)
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);
104 if (manager!=0)
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);
126 #ifdef SIGPOLL
127 signal(SIGPOLL, &destruct);
128 #endif
129 #ifdef SIGSYS
130 signal(SIGSYS, &destruct);
131 #endif
132 #ifdef SIGVTALRM
133 signal(SIGVTALRM, &destruct);
134 #endif
135 #ifdef SIGXCPU
136 signal(SIGXCPU, &destruct);
137 #endif
138 #ifdef SIGXFSZ
139 signal(SIGXFSZ, &destruct);
140 #endif
143 #ifdef GNU_GETOPT
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'},
153 {0, 0, 0, 0}
155 #endif
157 int main(int argc, char** argv)
159 int quiet(0);
160 int c(0);
161 int configStyle(UNIXCONFIGSTYLE);
162 MyString configFile;
163 int portToUse(MYPORT);
165 //I thought this would be the way to check wether long options are supported...
166 #ifdef GNU_GETOPT
167 while ((c=getopt_long(argc, argv, "vqukKc:h", long_opts, 0))!=-1)
168 #else
169 while ((c=getopt(argc, argv, "vqukKc:h"))!=-1)
170 #endif
172 switch (c)
174 case 0:
175 break;
176 case 'v':
177 printVersion();
178 exit(0);
179 break;
180 case 'q':
181 quiet=1;
182 break;
183 case 'u':
184 case 'k':
185 case 'K':
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;
191 break;
193 case 'c':
194 configFile = optarg;
195 configStyle = EXTRACONFIGSTYLE;
196 break;
198 case 'h':
199 default:
200 usage();
201 exit(0);
202 break;
206 //fork and let the parent exit
207 pid_t pid=fork();
208 if (pid>0)
210 //this is the parent
211 exit(0);
213 else if (pid<0)
215 dcerr<<"could not fork()"<<std::endl;
216 exit(0);
218 //we will only read/write to/from this socket in the child process
219 int rawSocket=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
220 if (rawSocket==-1)
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;
224 exit(0);
226 int bufferSize(60*1024);
227 int on(1);
228 setsockopt(rawSocket, SOL_SOCKET, SO_RCVBUF, (char*)&bufferSize,
229 sizeof(bufferSize));
230 int result=setsockopt(rawSocket, SOL_SOCKET, SO_BROADCAST, (char*)&on,
231 sizeof(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
238 setuid(getuid());
240 //according to R. Stevens the following three lines
241 //make daemons feel good :)
242 setsid();
243 chdir("/");
244 umask(0);
246 dcerr<<"starting, dropped root privileges"<<std::endl;
247 dcerr<<"port: "<<portToUse<<" file: "<<configFile<<std::endl;
248 NetManager netmanager(rawSocket,portToUse,configFile,configStyle,1);
249 manager=&netmanager;
250 dcerr<<"NetManager created"<<std::endl;
251 setSignalHandler();
253 netmanager.readConfig();
254 if (netmanager.prepare())
256 if (!quiet)
257 printVersion();
258 netmanager.run();
260 dcerr<<"server finished"<<std::endl;