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"
28 #define dcerr if (LISA_DEBUG==1) std::cerr<<"main "
33 #include <sys/types.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>
42 // only gnu libc has getopt.h... getopt(3) is defined to be in unistd.h
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
;
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...
81 // std::cout<<"Please note that the long options are not supported on
82 // this system"<<std::endl;
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);
95 manager
->~NetManager();
99 void readConfig(int sigNumber
)
101 dcerr
<<"readConfig(): signal caught: "<<sigNumber
<<std::endl
;
102 signal(SIGHUP
,SIG_IGN
);
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
);
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
);
135 signal(SIGPOLL
, &destruct
);
138 signal(SIGSYS
, &destruct
);
141 signal(SIGVTALRM
, &destruct
);
144 signal(SIGXCPU
, &destruct
);
147 signal(SIGXFSZ
, &destruct
);
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'},
166 int main(int argc
, char** argv
)
170 int configStyle(UNIXCONFIGSTYLE
);
172 int portToUse(MYPORT
);
174 //I thought this would be the way to check wether long options are supported...
176 while ((c
=getopt_long(argc
, argv
, "vqukKc:h", long_opts
, 0))!=-1)
178 while ((c
=getopt(argc
, argv
, "vqukKc:h"))!=-1)
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
;
208 configStyle
= EXTRACONFIGSTYLE
;
212 portToUse
=strtol(optarg
,&endp
,10);
228 //fork and let the parent exit
237 std::cout
<<"could not fork()"<<std::endl
;
240 //we will only read/write to/from this socket in the child process
241 int rawSocket
=socket(AF_INET
,SOCK_RAW
,IPPROTO_ICMP
);
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
;
248 int bufferSize(60*1024);
250 setsockopt(rawSocket
, SOL_SOCKET
, SO_RCVBUF
, (char*)&bufferSize
,
252 int result
=setsockopt(rawSocket
, SOL_SOCKET
, SO_BROADCAST
, (char*)&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
263 if (geteuid() != getuid())
266 //according to R. Stevens the following three lines
267 //make daemons feel good :)
272 dcerr
<<"starting, dropped root privileges"<<std::endl
;
273 dcerr
<<"port: "<<portToUse
<<" file: "<<configFile
<<std::endl
;
274 NetManager
netmanager(rawSocket
,portToUse
,configFile
,configStyle
,0);
276 dcerr
<<"NetManager created"<<std::endl
;
279 netmanager
.readConfig();
280 if (netmanager
.prepare())
285 std::cout
<<"\n\rrunning on port "<<portToUse
<<"\n\rHave fun ! :-)"<<std::endl
;
289 dcerr
<<"server finished"<<std::endl
;