2 * KFontInst - KDE Font Installer
4 * Copyright 2003-2007 Craig Drummond <craig@kde.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
25 // This file contains code taken from kdebase/runtime/kdesu/kdesud/kdesud.cpp
34 #include <sys/types.h>
35 #include <sys/socket.h>
39 #include <QtCore/QFile>
40 #include <QtCore/QDir>
41 #include <QtCore/QFileInfo>
42 #include <config-workspace.h>
43 #include <KDE/KStandardDirs>
50 #define SUN_LEN(ptr) ((socklen_t) (((struct sockaddr_un *) 0)->sun_path) \
51 + strlen ((ptr)->sun_path))
54 typedef unsigned ksocklen_t
;
59 #define KFI_SOCKET_SUFFIX "kio_fonts_"
60 #define KFI_SOCKET_SUFFIX_LEN 10
66 int thisPid(getpid());
68 sockName
.sprintf(KFI_SOCKET_SUFFIX
"%d", thisPid
);
70 QString
nameAndPath(KStandardDirs::locateLocal("socket", sockName
));
72 itsName
=QFile::encodeName(nameAndPath
);
74 // Remove any old sockets that are no longer active
75 QDir
dir(Misc::getDir(nameAndPath
));
76 QStringList nameFilters
;
78 nameFilters
.append(KFI_SOCKET_SUFFIX
"*");
79 dir
.setFilter(QDir::System
|QDir::CaseSensitive
);
80 dir
.setNameFilters(nameFilters
);
82 QFileInfoList
list(dir
.entryInfoList());
84 for (int i
= 0; i
< list
.size(); ++i
)
86 QFileInfo
fileInfo(list
.at(i
));
88 if(fileInfo
.ownerId()==getuid() && fileInfo
.groupId()==getgid())
90 int pid
=fileInfo
.fileName().mid(KFI_SOCKET_SUFFIX_LEN
).toInt();
92 if(0!=pid
&& pid
!=thisPid
&& 0!=kill(pid
, 0))
93 ::unlink(QFile::encodeName(fileInfo
.absoluteFilePath()));
106 int stat_err
=lstat(itsName
, &s
);
107 if(!stat_err
&& S_ISLNK(s
.st_mode
))
109 kWarning() << "Someone is running a symlink attack on you" ;
112 kWarning() << "Could not delete symlink" ;
117 if (!access(itsName
, R_OK
|W_OK
))
119 kWarning() << "stale socket exists" ;
122 kWarning() << "Could not delete stale socket" ;
127 itsFd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
130 kError() << "socket(): " << strerror(errno
) << endl
;
134 struct sockaddr_un addr
;
135 addr
.sun_family
= AF_UNIX
;
136 strncpy(addr
.sun_path
, itsName
, sizeof(addr
.sun_path
)-1);
137 addr
.sun_path
[sizeof(addr
.sun_path
)-1] = '\000';
138 addrlen
= SUN_LEN(&addr
);
139 if (bind(itsFd
, (struct sockaddr
*)&addr
, addrlen
) < 0)
141 kError() << "bind(): " << strerror(errno
) << endl
;
146 lin
.l_onoff
= lin
.l_linger
= 0;
147 if (setsockopt(itsFd
, SOL_SOCKET
, SO_LINGER
, (char *) &lin
,
150 kError() << "setsockopt(SO_LINGER): " << strerror(errno
) << endl
;
155 if (setsockopt(itsFd
, SOL_SOCKET
, SO_REUSEADDR
, (char *) &opt
,
158 kError() << "setsockopt(SO_REUSEADDR): " << strerror(errno
) << endl
;
162 if (setsockopt(itsFd
, SOL_SOCKET
, SO_KEEPALIVE
, (char *) &opt
,
165 kError() << "setsockopt(SO_KEEPALIVE): " << strerror(errno
) << endl
;
168 chmod(itsName
, 0600);
169 if (listen(itsFd
, 1) < 0)
171 kError() << "listen(): " << strerror(errno
) << endl
;
179 void CServer::close()
183 if(!itsName
.isEmpty())
188 CSocket
* CServer::waitForClient(int timeout
)
200 FD_SET(itsFd
, &fdSet
);
202 if(select(itsFd
+ 1, &fdSet
, NULL
, NULL
, &tv
)<0)
207 kError() << "select(): " << strerror(errno
) << endl
;
211 if(FD_ISSET(itsFd
, &fdSet
))
213 struct sockaddr_un clientname
;
214 ksocklen_t
addrlen(64);
217 if((fd
=accept(itsFd
, (struct sockaddr
*) &clientname
, &addrlen
))>=0)
218 return new CSocket(fd
);
222 kError() << "select timeout" << endl
;