View | Details | Raw Unified | Return to bug 8312
Collapse All | Expand All

(-)net-scripts-0.4.9.1/src/ppp-watch.c (-1 / +125 lines)
Lines 75-80 Link Here
75
#include <sys/wait.h>
75
#include <sys/wait.h>
76
#include <termios.h>
76
#include <termios.h>
77
#include <net/if.h>
77
#include <net/if.h>
78
#include <glob.h>
78
79
79
#include "shvar.h"
80
#include "shvar.h"
80
#include "alloc.h"
81
#include "alloc.h"
Lines 116-121 Link Here
116
}
117
}
117
118
118
119
120
// Returns pid of pppd (must be /usr/sbin/pppd) process that has
121
// "linkname device" in its command line. 0 if not found, -1 on error.
122
static int
123
get_pppd_pid(char *device) {
124
    int i;
125
    glob_t globbuf;
126
    int ge = glob("/proc/*/cmdline", 0, NULL, &globbuf);
127
    if (!ge) {
128
	for (i = 0; i < globbuf.gl_pathc; ++i) {	    
129
	    FILE *fcmdline;
130
	    char cmdline[1024]; // hope this will be enough
131
	    if (fcmdline = fopen(globbuf.gl_pathv[i], "r")) {
132
		int num_read;
133
		num_read = fread(cmdline, 1, 1024, fcmdline);
134
		if (num_read > 0 && !strcmp(cmdline, "/usr/sbin/pppd")) {
135
		    int prev_linkname = 0;
136
		    char *p = cmdline;
137
		    while (*p && p - cmdline < 1024) {
138
			if (prev_linkname && !strcmp(p, device)) {
139
			    int retval;
140
			    globbuf.gl_pathv[i][strlen(globbuf.gl_pathv[i])-8] = 0;
141
			    retval = atoi(globbuf.gl_pathv[i]+6);
142
			    globfree(&globbuf);
143
			    fclose(fcmdline);
144
			    return retval;
145
			}
146
			prev_linkname = !strcmp(p, "linkname");
147
			p += strlen(p) + 1;
148
		    }		    
149
		}
150
		fclose(fcmdline);
151
	    }
152
	}
153
	globfree(&globbuf);
154
	return 0;
155
    }
156
    else
157
	return -1;
158
}
159
160
// If there exists only one child of specified process, returns its pid.
161
// Otherwise (if no children or more than 1) returns 0. -1 on error.
162
static int get_only_child(int parent_pid) {
163
    int i;
164
    glob_t globbuf;
165
    int ge = glob("/proc/*/status", 0, NULL, &globbuf);
166
    if (!ge) {
167
        int result_pid = 0;
168
	for (i = 0; i < globbuf.gl_pathc; ++i) {	    
169
	    FILE *fstatus;
170
	    char status[1024]; // hope this will be enough
171
	    if (fstatus = fopen(globbuf.gl_pathv[i], "r")) {
172
		int num_read;
173
		num_read = fread(status, 1, 1023, fstatus);
174
		if (num_read > 0) {			
175
		    char *ppid_pos;
176
		    status[num_read] = 0;
177
		    ppid_pos = strstr(status, "PPid:\t");
178
		    if (ppid_pos)
179
		    {
180
			int cur_ppid = atoi(ppid_pos+6);
181
			if (cur_ppid == parent_pid)
182
			{
183
			    // Heuristics: we look only for those chldren
184
			    // which have non-empty commandline
185
			    char cmdline[256], *p;
186
			    FILE *fcmdline;
187
			    strcpy(cmdline, globbuf.gl_pathv[i]);
188
			    for(p=cmdline+strlen(cmdline); *p!='/' && p>=cmdline; --p);
189
			    ++p;
190
			    strcpy(p, "cmdline");			    
191
			    if (!(fcmdline = fopen(cmdline, "r")) 
192
			        || !fread(cmdline, 1, 256, fcmdline))
193
			    {
194
				fclose(fstatus);
195
				continue;
196
			    }
197
			    fclose(fcmdline);
198
			    if (result_pid)
199
			    {
200
				globfree(&globbuf);
201
				fclose(fstatus);
202
				return 0;
203
			    }
204
			    else
205
				result_pid = atoi(globbuf.gl_pathv[i]+6);
206
			}
207
		    }
208
		}
209
		fclose(fstatus);
210
	    }
211
	}
212
	globfree(&globbuf);
213
	return result_pid;
214
    }
215
    else
216
	return -1;
217
}
119
218
120
static void
219
static void
121
detach(int now, int parentExitCode, char *device) {
220
detach(int now, int parentExitCode, char *device) {
Lines 541-546 Link Here
541
	    sigsuspend(&unblockedsigs);
640
	    sigsuspend(&unblockedsigs);
542
641
543
	if (theSigterm || theSigint) {
642
	if (theSigterm || theSigint) {
643
	    int proc_pppd_pid, chat_pid, i;
544
	    theSigterm = theSigint = 0;
644
	    theSigterm = theSigint = 0;
545
645
546
	    if (dieing) sendsig = SIGKILL;
646
	    if (dieing) sendsig = SIGKILL;
Lines 550-555 Link Here
550
	    if (physicalDevice) { free(physicalDevice); physicalDevice = NULL; }
650
	    if (physicalDevice) { free(physicalDevice); physicalDevice = NULL; }
551
	    physicalDevice = pppLogicalToPhysical(&pppdPid, real_device);
651
	    physicalDevice = pppLogicalToPhysical(&pppdPid, real_device);
552
	    if (physicalDevice) { free(physicalDevice); physicalDevice = NULL; }
652
	    if (physicalDevice) { free(physicalDevice); physicalDevice = NULL; }
653
	    // We suspect that pppd is running, but haven't created
654
	    // .pid file yet. Keep waiting for .pid file and try 
655
	    // to find chat or whatever pppd uses
656
	    // to establish connection.
657
	    for (i=0; !pppdPid && (proc_pppd_pid = get_pppd_pid(device))
658
	              && !(chat_pid = get_only_child(proc_pppd_pid))
659
	              && i<60000;
660
	         ++i)
661
	    {
662
		physicalDevice = pppLogicalToPhysical(&pppdPid, real_device);
663
		if (physicalDevice) { free(physicalDevice); physicalDevice = NULL; }
664
		usleep(1000);
665
	    }
666
	    if (pppdPid)
667
		sleep(2); // Else pppd may hangup, seems there's a bug in it
668
	    else
669
		if (chat_pid)
670
		{
671
		    // Found chat or whatever. 
672
		    // Let's kill it instead of pppd.
673
		    pppdPid = chat_pid;
674
		}
553
	    if (!pppdPid) cleanExit(35);
675
	    if (!pppdPid) cleanExit(35);
554
	    kill(pppdPid, sendsig);
676
	    kill(pppdPid, sendsig);
555
	    if (sendsig == SIGKILL) {
677
	    if (sendsig == SIGKILL) {
Lines 617-623 Link Here
617
	    pppdPid = 0;
739
	    pppdPid = 0;
618
740
619
	    if (!WIFEXITED(status)) cleanExit(29);
741
	    if (!WIFEXITED(status)) cleanExit(29);
620
	    if (dieing) cleanExit(WEXITSTATUS(status));
742
	    // We want to know if user terminated dialing, even if it was
743
	    // during execution of connect script.
744
	    if (dieing) cleanExit(WEXITSTATUS(status)==8?5:WEXITSTATUS(status));
621
745
622
	    /* error conditions from which we do not expect to recover
746
	    /* error conditions from which we do not expect to recover
623
	     * without user intervention -- do not fill up the logs.
747
	     * without user intervention -- do not fill up the logs.

Return to bug 8312