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