1 | /* |
2 | * |
3 | * kPPP: A pppd front end for the KDE project |
4 | * |
5 | * $Id$ |
6 | * |
7 | * (c) 1998 Mario Weilguni <mweilguni@kde.org> |
8 | * |
9 | * Copyright (C) 1997 Bernd Johannes Wuebben |
10 | * wuebben@math.cornell.edu |
11 | * |
12 | * based on EzPPP: |
13 | * Copyright (C) 1997 Jay Painter |
14 | * |
15 | * This program is free software; you can redistribute it and/or |
16 | * modify it under the terms of the GNU Library General Public |
17 | * License as published by the Free Software Foundation; either |
18 | * version 2 of the License, or (at your option) any later version. |
19 | * |
20 | * This program is distributed in the hope that it will be useful, |
21 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
23 | * Library General Public License for more details. |
24 | * |
25 | * You should have received a copy of the GNU Library General Public |
26 | * License along with this program; if not, write to the Free |
27 | * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
28 | */ |
29 | |
30 | #include <qlabel.h> |
31 | #include <qdir.h> |
32 | #include <qpushbutton.h> |
33 | //Added by qt3to4: |
34 | #include <QVBoxLayout> |
35 | #include <stdio.h> |
36 | #include <stdlib.h> |
37 | #include <string.h> |
38 | #include <ctype.h> |
39 | #include <unistd.h> |
40 | #include <sys/stat.h> |
41 | |
42 | #include <kdialog.h> |
43 | #include <qregexp.h> |
44 | #include <QTextEdit> |
45 | #include <qlayout.h> |
46 | |
47 | #include <kmessagebox.h> |
48 | #include <kvbox.h> |
49 | |
50 | #include "pppdata.h" |
51 | #include "requester.h" |
52 | #include <klocale.h> |
53 | |
54 | |
55 | int PPPL_MakeLog(QStringList &list) { |
56 | int pid = -1, newpid; |
57 | char buffer[1024], *p; |
58 | const char *pidp; |
59 | int fd; |
60 | |
61 | fd = Requester::rq->openSysLog(); |
62 | if(fd < 0) { |
63 | list.append(i18n("Cannot open any of the following logfiles:" )); |
64 | const char * const * logFile = &kppp_syslog[0]; |
65 | while(*logFile) { |
66 | list.append(*logFile); |
67 | logFile++; |
68 | } |
69 | return 1; |
70 | } |
71 | |
72 | FILE *f = fdopen(fd, "r" ); |
73 | while(fgets(buffer, sizeof(buffer), f) != 0) { |
74 | // pppd line ? |
75 | p = (char *)strstr(buffer, "pppd[" ); |
76 | if(p == 0) |
77 | continue; |
78 | pidp = p += strlen("pppd[" ); |
79 | while(*p && isdigit(*p)) |
80 | p++; |
81 | if(*p != ']') |
82 | continue; |
83 | |
84 | /* find out pid of pppd */ |
85 | sscanf(pidp, "%d" , &newpid); |
86 | if(newpid != pid) { |
87 | pid = newpid; |
88 | list.clear(); |
89 | } |
90 | if(buffer[strlen(buffer)-1] == '\n') |
91 | buffer[strlen(buffer)-1] = '\0'; |
92 | list.append(buffer); |
93 | } |
94 | fclose(f); |
95 | |
96 | if(list.isEmpty()) |
97 | return 2; |
98 | |
99 | /* clear security related info */ |
100 | |
101 | const char *keyword[] = {"name = \"" , |
102 | "user=\"" , |
103 | "password=\"" , |
104 | 0}; |
105 | |
106 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) |
107 | { |
108 | QByteArray tmp = (*it).toLocal8Bit(); |
109 | for(int j = 0; keyword[j] != 0; j++) { |
110 | char *p; |
111 | |
112 | if( (p = (char *)strstr(tmp.data(), keyword[j])) != 0) { |
113 | p += strlen(keyword[j]); |
114 | while(*p && *p != '"') |
115 | *p++ = 'X'; |
116 | } |
117 | } |
118 | |
119 | } |
120 | |
121 | return 0; |
122 | } |
123 | |
124 | |
125 | void PPPL_AnalyseLog(QStringList &list, QStringList &result) { |
126 | QString msg; |
127 | const char *rmsg = "Remote message: " ; |
128 | |
129 | result.clear(); |
130 | |
131 | // setup the analysis database |
132 | struct { |
133 | const char *regexp; |
134 | const char *answer; |
135 | } hints[] = { |
136 | {"Receive serial link is not 8-bit clean" , |
137 | I18N_NOOP("You have launched pppd before the remote server " \ |
138 | "was ready to establish a PPP connection.\n" |
139 | "Please use the terminal-based login to verify" ) }, |
140 | |
141 | {"Serial line is looped back" , |
142 | I18N_NOOP("You have not started the PPP software on the peer system." ) }, |
143 | |
144 | {"AP authentication failed" , |
145 | I18N_NOOP("Check that you supplied the correct username and password." )} , |
146 | |
147 | {"is locked by pid" , |
148 | I18N_NOOP("You should not pass 'lock' as an argument to pppd. " |
149 | "Check /etc/ppp/options and ~/.ppprc" ) }, |
150 | |
151 | {"CP: timeout sending" , |
152 | I18N_NOOP("The remote system does not seem to answer to\n" |
153 | "configuration request. Contact your provider." ) }, |
154 | |
155 | {"unrecognized option" , |
156 | I18N_NOOP("You have passed an invalid option to pppd. See 'man pppd' " |
157 | "for a complete list of valid arguments." ) }, |
158 | |
159 | // terminator |
160 | {0,0} |
161 | }; |
162 | |
163 | |
164 | // scan the log for keywords and try to offer any help |
165 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) |
166 | { |
167 | // look for remote message |
168 | int pos = (*it).indexOf(rmsg); |
169 | if (pos != -1) |
170 | { |
171 | QString str = (*it); |
172 | str.remove(0, pos + strlen(rmsg)); |
173 | if(!str.isEmpty()) { |
174 | msg = i18n("Notice that the remote system has sent the following" |
175 | " message:\n\"%1\"\nThis may give you a hint why the" |
176 | " connection has failed." , str); |
177 | result.append(msg); |
178 | } |
179 | } |
180 | |
181 | // check in the hint database |
182 | for(uint k = 0; hints[k].regexp != 0; k++) { |
183 | QRegExp rx(hints[k].regexp); |
184 | QString l(*it); |
185 | if(l.contains(rx)) { |
186 | result.append(i18n(hints[k].answer)); |
187 | break; |
188 | } |
189 | } |
190 | } |
191 | |
192 | if (result.isEmpty()) |
193 | result.append(i18n("Unable to provide help." )); |
194 | } |
195 | |
196 | |
197 | void PPPL_ShowLog() { |
198 | QStringList sl, result; |
199 | |
200 | PPPL_MakeLog(sl); |
201 | |
202 | bool foundConnect = false; |
203 | bool foundLCP = gpppdata.getPPPDebug(); |
204 | QString lcp = QLatin1String("[LCP" ); |
205 | QString conn = QLatin1String("Connect:" ); |
206 | QStringList::ConstIterator it = sl.constBegin(); |
207 | for( ; it != sl.constEnd(); it++) { |
208 | if((*it).indexOf(lcp) >= 0) { |
209 | foundLCP = true; |
210 | break; |
211 | } |
212 | if((*it).contains(conn)) |
213 | foundConnect = true; |
214 | } |
215 | if(foundConnect && !foundLCP) { |
216 | int result = KMessageBox::warningYesNo(0, |
217 | i18n("KPPP could not prepare a PPP log. It is very likely " |
218 | "that pppd was started without the \"debug\" option.\n" |
219 | "Without this option it is difficult to find out PPP " |
220 | "problems, so in general the debug option should be used.\n" |
221 | "Enable debug now, and restart pppd?" ), QString(), KGuiItem(i18n("Restart pppd" )), KGuiItem(i18n("Do Not Restart" ))); |
222 | |
223 | if(result == KMessageBox::Yes) { |
224 | gpppdata.setPPPDebug(true); |
225 | KMessageBox::information(0, |
226 | i18n("The \"debug\" option has been added. You " |
227 | "should now try to reconnect. If that fails " |
228 | "again, you will get a PPP log that may help " |
229 | "you to track down the connection problem." )); |
230 | // return; |
231 | } |
232 | |
233 | // return; |
234 | } |
235 | |
236 | PPPL_AnalyseLog(sl, result); |
237 | |
238 | KDialog *dlg = new KDialog(); |
239 | dlg->setButtons(KDialog::Close | KDialog::Ok); |
240 | dlg->setWindowTitle(i18n("PPP Log" )); |
241 | dlg->setButtonText(KDialog::Ok,i18n("Write to File" )); |
242 | |
243 | KVBox* v = new KVBox(dlg); |
244 | QTextEdit *edit = new QTextEdit(v); |
245 | edit->setReadOnly(true); |
246 | QLabel *label = new QLabel(i18n("kppp's diagnosis (just guessing):" ), v); |
247 | QTextEdit *diagnosis = new QTextEdit(v); |
248 | diagnosis->setReadOnly(true); |
249 | edit->setMinimumSize(600, 250); |
250 | label->setMinimumSize(600, 15); |
251 | diagnosis->setMinimumSize(600, 60); |
252 | |
253 | dlg->setMainWidget(v); |
254 | |
255 | for(int i = 0; i < sl.count(); i++) |
256 | edit->append(sl.at(i)); |
257 | for(int i = 0; i < result.count(); i++) |
258 | diagnosis->append(result.at(i)); |
259 | |
260 | if(dlg->exec()) { |
261 | QDir d = QDir::home(); |
262 | QString s = d.absolutePath() + "/PPP-logfile" ; |
263 | int old_umask = umask(0077); |
264 | |
265 | FILE *f = fopen(QFile::encodeName(s), "w" ); |
266 | for(int i = 0; i < sl.count(); i++) |
267 | fprintf(f, "%s\n" , sl.at(i).toLocal8Bit().data()); |
268 | fclose(f); |
269 | umask(old_umask); |
270 | |
271 | QString msg = i18n("The PPP log has been saved\nas \"%1\".\n\nIf you want to send a bug report, or have\nproblems connecting to the Internet, please\nattach this file. It will help the maintainers\nto find the bug and to improve KPPP" , s); |
272 | KMessageBox::information(0, msg); |
273 | } |
274 | delete dlg; |
275 | } |
276 | |