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