]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/afp_asp.c
57c25a7a400515beeb3ddbc6e81c26fc79269652
[netatalk.git] / etc / afpd / afp_asp.c
1 /* 
2  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
3  * Copyright (c) 1990,1993 Regents of The University of Michigan.
4  * All Rights Reserved.  See COPYRIGHT.
5  *
6  * modified from main.c. this handles afp over asp. 
7  */
8
9 #ifndef NO_DDP
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <signal.h>
15 #include <syslog.h>
16 #include <sys/time.h>
17 #include <sys/stat.h>
18
19 #include <netatalk/endian.h>
20 #include <atalk/atp.h>
21 #include <atalk/asp.h>
22 #include <atalk/compat.h>
23 #include <atalk/util.h>
24
25 #include "globals.h"
26 #include "switch.h"
27 #include "auth.h"
28 #include "fork.h"
29
30 extern struct oforks    *writtenfork;
31
32 /* for CAP style authenticated printing */
33 #ifdef CAPDIR
34 extern int addr_net, addr_node, addr_uid;
35 #endif /* CAPDIR */
36
37 static AFPObj *child;
38
39 static __inline__ void afp_asp_close(AFPObj *obj)
40 {
41     ASP asp = obj->handle;
42     
43     if (obj->logout)
44       (*obj->logout)();
45
46     asp_close( asp );
47     syslog(LOG_INFO, "%.2fKB read, %.2fKB written",
48            asp->read_count / 1024.0, asp->write_count / 1024.0);
49 }
50
51 static void afp_asp_die(const int sig)
52 {
53     ASP asp = child->handle;
54
55     asp_attention(asp, AFPATTN_SHUTDOWN);
56     if ( asp_shutdown( asp ) < 0 ) {
57         syslog( LOG_ERR, "afp_die: asp_shutdown: %m" );
58     }
59
60     afp_asp_close(child);
61     if (sig == SIGTERM || sig == SIGALRM)
62       exit( 0 );
63     else
64       exit(sig);
65 }
66
67 static void afp_asp_timedown()
68 {
69     struct sigaction    sv;
70     struct itimerval    it;
71
72     /* shutdown and don't reconnect. server going down in 5 minutes. */
73     asp_attention(child->handle, AFPATTN_SHUTDOWN | AFPATTN_NORECONNECT |
74                   AFPATTN_TIME(5));
75
76     it.it_interval.tv_sec = 0;
77     it.it_interval.tv_usec = 0;
78     it.it_value.tv_sec = 300;
79     it.it_value.tv_usec = 0;
80     if ( setitimer( ITIMER_REAL, &it, 0 ) < 0 ) {
81         syslog( LOG_ERR, "afp_timedown: setitimer: %m" );
82         afp_asp_die(1);
83     }
84
85     memset(&sv, 0, sizeof(sv));
86     sv.sa_handler = afp_asp_die;
87     sigemptyset( &sv.sa_mask );
88     sv.sa_flags = SA_RESTART;
89     if ( sigaction( SIGALRM, &sv, 0 ) < 0 ) {
90         syslog( LOG_ERR, "afp_timedown: sigaction: %m" );
91         afp_asp_die(1);
92     }
93 }
94
95 void afp_over_asp(AFPObj *obj)
96 {
97     ASP asp;
98     struct sigaction  action;
99     int         func, ccnt = 0, reply = 0;
100
101 #ifdef CAPDIR
102     char addr_filename[256];
103     struct stat cap_st;
104 #endif /* CAPDIR */
105
106     obj->exit = afp_asp_die;
107     obj->reply = (int (*)()) asp_cmdreply;
108     obj->attention = (int (*)(void *, AFPUserBytes)) asp_attention;
109     child = obj;
110     asp = (ASP) obj->handle;
111
112     /* install signal handlers */
113     memset(&action, 0, sizeof(action));
114     action.sa_handler = afp_asp_timedown;
115     sigemptyset( &action.sa_mask );
116     action.sa_flags = SA_RESTART;
117     if ( sigaction( SIGHUP, &action, 0 ) < 0 ) {
118         syslog( LOG_ERR, "afp_over_asp: sigaction: %m" );
119         afp_asp_die(1);
120     }
121
122     action.sa_handler = afp_asp_die;
123     sigemptyset( &action.sa_mask );
124     action.sa_flags = SA_RESTART;
125     if ( sigaction( SIGTERM, &action, 0 ) < 0 ) {
126         syslog( LOG_ERR, "afp_over_asp: sigaction: %m" );
127         afp_asp_die(1);
128     }
129
130 #ifdef CAPDIR
131     addr_net = ntohs( asp->asp_sat.sat_addr.s_net );
132     addr_node  = asp->asp_sat.sat_addr.s_node;
133 #endif /* CAPDIR */
134
135     syslog( LOG_INFO, "session from %u.%u:%u on %u.%u:%u",
136             ntohs( asp->asp_sat.sat_addr.s_net ),
137             asp->asp_sat.sat_addr.s_node, asp->asp_sat.sat_port,
138             ntohs( atp_sockaddr( asp->asp_atp )->sat_addr.s_net ),
139             atp_sockaddr( asp->asp_atp )->sat_addr.s_node,
140             atp_sockaddr( asp->asp_atp )->sat_port );
141
142     while ((reply = asp_getrequest(asp))) {
143       switch (reply) {
144       case ASPFUNC_CLOSE :
145         afp_asp_close(obj);
146         syslog( LOG_INFO, "done" );
147
148 #ifdef CAPDIR
149         sprintf(addr_filename, "%s/net%d.%dnode%d", CAPDIR, addr_net/256, addr_net%256, addr_node);
150         if(stat(addr_filename, &cap_st) == 0) {
151                 if(unlink(addr_filename) == 0) {
152                         syslog(LOG_INFO, "removed %s", addr_filename);
153                 } else {
154                         syslog(LOG_INFO, "error removing %s: %m", addr_filename);
155                 }
156         } else {
157                 syslog(LOG_INFO, "error stat'ing %s: %m", addr_filename);
158         }
159 #endif /* CAPDIR */
160
161         if ( obj->options.flags & OPTION_DEBUG ) {
162           printf( "done\n" );
163         }
164         return;
165         break;
166
167       case ASPFUNC_CMD :
168 #ifdef AFS
169         if ( writtenfork ) {
170           if ( flushfork( writtenfork ) < 0 ) {
171             syslog( LOG_ERR, "main flushfork: %m" );
172           }
173           writtenfork = NULL;
174         }
175 #endif AFS
176         func = (u_char) asp->commands[0];
177         if ( obj->options.flags & OPTION_DEBUG ) {
178           printf( "command: %d\n", func );
179           bprint( asp->commands, asp->cmdlen );
180         }
181         if ( afp_switch[ func ] != NULL ) {
182           /*
183            * The function called from afp_switch is expected to
184            * read its parameters out of buf, put its
185            * results in replybuf (updating rbuflen), and
186            * return an error code.
187                  */
188           asp->datalen = ASP_DATASIZ;
189           reply = (*afp_switch[ func ])(obj,
190                                         asp->commands, asp->cmdlen,
191                                         asp->data, &asp->datalen);
192         } else {
193           syslog( LOG_ERR, "bad function %X", func );
194           asp->datalen = 0;
195           reply = AFPERR_NOOP;
196         }
197         if ( obj->options.flags & OPTION_DEBUG ) {
198           printf( "reply: %d, %d\n", reply, ccnt++ );
199           bprint( asp->data, asp->datalen );
200         }
201
202         if ( asp_cmdreply( asp, reply ) < 0 ) {
203           syslog( LOG_ERR, "asp_cmdreply: %m" );
204           afp_asp_die(1);
205         }
206         break;
207
208       case ASPFUNC_WRITE :
209         func = (u_char) asp->commands[0];
210         if ( obj->options.flags & OPTION_DEBUG ) {
211           printf( "(write) command: %d\n", func );
212           bprint( asp->commands, asp->cmdlen );
213         }
214         if ( afp_switch[ func ] != NULL ) {
215           asp->datalen = ASP_DATASIZ;
216           reply = (*afp_switch[ func ])(obj, 
217                                         asp->commands, asp->cmdlen,
218                                         asp->data, &asp->datalen);
219         } else {
220           syslog( LOG_ERR, "(write) bad function %X", func );
221           asp->datalen = 0;
222           reply = AFPERR_NOOP;
223         }
224         if ( obj->options.flags & OPTION_DEBUG ) {
225           printf( "(write) reply code: %d, %d\n", reply, ccnt++ );
226           bprint( asp->data, asp->datalen );
227         }
228         if ( asp_wrtreply( asp, reply ) < 0 ) {
229           syslog( LOG_ERR, "asp_wrtreply: %m" );
230           afp_asp_die(1);
231         }
232         break;
233       default:
234         /*
235            * Bad asp packet.  Probably should have asp filter them,
236            * since they are typically things like out-of-order packet.
237            */
238         syslog( LOG_INFO, "main: asp_getrequest: %d", reply );
239         break;
240       }
241
242       if ( obj->options.flags & OPTION_DEBUG ) {
243 #ifdef notdef
244         pdesc( stdout );
245 #endif notdef
246         of_pforkdesc( stdout );
247         fflush( stdout );
248       }
249     }
250 }
251
252 #endif