]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/afp_asp.c
Inserted changelog of version 1.5pre6-6.
[netatalk.git] / etc / afpd / afp_asp.c
1 /* 
2  * $Id: afp_asp.c,v 1.5 2001-06-20 18:33:04 rufustfirefly 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