Correct utmp handling - Robert Davidson <puttputt@iaccess.ws>
[ppp.git] / pppd / plugins / pppoe / pppd_utils.c
1 /* PPPoE support library "libpppoe"
2  *
3  * Copyright 2000 Michal Ostrowski <mostrows@styx.uwaterloo.ca>,
4  *                Jamal Hadi Salim <hadi@cyberus.ca>
5  *
6  *  This program is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU General Public License
8  *  as published by the Free Software Foundation; either version
9  *  2 of the License, or (at your option) any later version.
10  */
11 #include "pppoe.h"
12
13 /*
14  *
15  */
16 int build_ppp_opts(char *args[],struct session *ses)
17 {
18     char buf[256];
19     int retval=0,i=0;
20     
21     memset(buf,0,256);
22     
23 /* pppds path */
24     if ( NULL != ses->filt->pppd){
25         args[0]=(char *)malloc(strlen(ses->filt->pppd));
26         strcpy (args[0],ses->filt->pppd);
27     } else {
28         args[0]=(char *)malloc(strlen(_PATH_PPPD));
29         strcpy (args[0],_PATH_PPPD);
30     }
31     
32 /*  long device name */
33     snprintf(buf, 256,"%02x:%02x:%02x:%02x:%02x:%02x/%04x/%s",
34              ses->remote.sll_addr[0],
35              ses->remote.sll_addr[1],
36              ses->remote.sll_addr[2],
37              ses->remote.sll_addr[3],
38              ses->remote.sll_addr[4],
39              ses->remote.sll_addr[5],
40              ses->sp.sa_addr.pppoe.sid,
41              ses->name);
42     args[1]=(char *)malloc(strlen(buf));
43     strcpy(args[1],buf);
44     
45     i=2;
46     
47 /* override options file */
48     if (NULL != ses->filt->fname ) {
49         
50         if (!ses->filt->peermode) {
51             args[i]=(char *)malloc(strlen("file"));
52             strcpy (args[i],"file");
53             i++;
54             args[i]=(char *)malloc(strlen(ses->filt->fname)+1);
55             strcpy (args[i],ses->filt->fname);
56             i++;
57         } else{ /* peermode */
58             args[i]=(char *)malloc(strlen("call"));
59             strcpy (args[i],"call");
60             i++;
61             args[i]=(char *)malloc(strlen(ses->filt->fname)+1);
62             strcpy (args[i],ses->filt->fname);
63             i++;
64         }
65     }
66     
67 /* user requested for a specific name */
68     if (NULL != ses->filt->ntag) {
69         if ( NULL != ses->filt->ntag->tag_data) {
70             args[i]=(char *)malloc(strlen("pppoe_ac_name"));
71             strcpy(args[i],"pppoe_ac_name");
72             i++;
73             args[i]=(char *)malloc(ntohs(ses->filt->ntag->tag_len));
74             strcpy(args[i],ses->filt->ntag->tag_data);
75             i++;
76         }
77     }
78 /* user requested for a specific service name */
79     if (NULL != ses->filt->stag) {
80         if ( NULL != ses->filt->stag->tag_data) {
81             args[i]=(char *)malloc(strlen("pppoe_srv_name"));
82             strcpy(args[i],"pppoe_srv_name");
83             i++;
84             args[i]=(char *)malloc(ntohs(ses->filt->stag->tag_len));
85             strcpy(args[i],ses->filt->stag->tag_data);
86             i++;
87         }
88     }
89     
90 /*
91  */
92     if (ses->opt_daemonize) {
93         args[i]=(char *)malloc(strlen("nodetach"));
94         strcpy(args[i],"nodetach");
95         i++;
96     }
97     
98     args[i]=NULL;
99     {
100         int j;
101         poe_info(ses,"calling pppd with %d args\n",i);
102         j=i;
103         for (i=0; i<j,NULL !=args[i]; i++) {
104             poe_info(ses," <%d: %s > \n",i,args[i]);
105         }
106     }
107     return retval;
108 }
109
110
111 /*
112  *
113  */
114 int ppp_connect (struct session *ses)
115 {
116     int ret,pid;
117     char *args[32];
118     
119     
120     poe_info(ses,"calling ses_connect\n");
121     do{
122         ret = session_connect(ses);
123     }while(ret == 0);
124
125     if (ret > 0 )
126         if (ses->np == 1 && ret == 1)
127             return ses->np; /* -G */
128     if (ses->np == 2)
129         return ses->np; /* -H */
130
131     if( ret <= 0){
132         return ret;
133     }
134     
135     poe_info(ses,"DONE calling ses_connect np is %d \n",ses->np);
136     
137     
138     pid = fork ();
139     if (pid < 0) {
140         poe_error (ses,"unable to fork() for pppd: %m");
141         poe_die (-1);
142     }
143     
144     
145     if(!pid) {
146         poe_info(ses,"calling build_ppp_opts\n");
147         if (0> build_ppp_opts(args,ses)) {
148             poe_error(ses,"ppp_connect: failed to build ppp_opts\n");
149             return -1;
150         }
151         execvp(args[0],args);
152         poe_info (ses," child got killed");
153     } else if( ses->type == SESSION_CLIENT) {
154         if (!ses->opt_daemonize)
155             return 1;
156         pause();
157         poe_info (ses," OK we got killed");
158         return -1;
159     }
160     return 1;
161 }
162