~ubuntu-branches/ubuntu/precise/netatalk/precise

« back to all changes in this revision

Viewing changes to etc/afpd/afp_asp.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Rittau
  • Date: 2004-01-19 12:43:49 UTC
  • Revision ID: james.westby@ubuntu.com-20040119124349-es563jbp0hk0ae51
Tags: upstream-1.6.4
ImportĀ upstreamĀ versionĀ 1.6.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: afp_asp.c,v 1.17 2002/08/30 19:32:40 didg 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 <atalk/logger.h>
 
22
#include <errno.h>
 
23
#ifdef HAVE_SYS_TIME_H
 
24
#include <sys/time.h>
 
25
#endif /* HAVE_SYS_TIME_H */
 
26
#ifdef HAVE_SYS_STAT_H
 
27
#include <sys/stat.h>
 
28
#endif /* HAVE_SYS_STAT_H */
 
29
 
 
30
#include <netatalk/endian.h>
 
31
#include <atalk/atp.h>
 
32
#include <atalk/asp.h>
 
33
#include <atalk/compat.h>
 
34
#include <atalk/util.h>
 
35
 
 
36
#include "globals.h"
 
37
#include "switch.h"
 
38
#include "auth.h"
 
39
#include "fork.h"
 
40
 
 
41
#ifdef FORCE_UIDGID
 
42
#warning UIDGID
 
43
#include "uid.h"
 
44
#endif /* FORCE_UIDGID */
 
45
 
 
46
extern struct oforks    *writtenfork;
 
47
 
 
48
static AFPObj *child;
 
49
 
 
50
static __inline__ void afp_authprint_remove(AFPObj *);
 
51
 
 
52
static __inline__ void afp_asp_close(AFPObj *obj)
 
53
{
 
54
    ASP asp = obj->handle;
 
55
 
 
56
    if (obj->options.authprintdir) afp_authprint_remove(obj);
 
57
 
 
58
    if (obj->logout)
 
59
        (*obj->logout)();
 
60
 
 
61
    LOG(log_info, logtype_afpd, "%.2fKB read, %.2fKB written",
 
62
        asp->read_count / 1024.0, asp->write_count / 1024.0);
 
63
    asp_close( asp );
 
64
}
 
65
 
 
66
/* removes the authprint trailing when appropriate */
 
67
static __inline__ void afp_authprint_remove(AFPObj *obj)
 
68
{
 
69
    ASP asp = obj->handle;
 
70
    char addr_filename[256];
 
71
    char addr_filename_buff[256];
 
72
    struct stat cap_st;
 
73
 
 
74
    sprintf(addr_filename, "%s/net%d.%dnode%d", obj->options.authprintdir,
 
75
                ntohs( asp->asp_sat.sat_addr.s_net )/256,
 
76
                ntohs( asp->asp_sat.sat_addr.s_net )%256,
 
77
                asp->asp_sat.sat_addr.s_node );
 
78
 
 
79
    memset( addr_filename_buff, 0, 256 );
 
80
 
 
81
    if(stat(addr_filename, &cap_st) == 0) {
 
82
        if( S_ISREG(cap_st.st_mode) ) {
 
83
            int len;
 
84
            int capfd = open( addr_filename, O_RDONLY );
 
85
            if ((len = read( capfd, addr_filename_buff, 256 )) > 0) {
 
86
                int file_pid;
 
87
                char *p_filepid;
 
88
                close(capfd);
 
89
                addr_filename_buff[len] = 0;
 
90
                if ( (p_filepid = strrchr(addr_filename_buff, ':')) != NULL) {
 
91
                    *p_filepid = '\0';
 
92
                    p_filepid++;
 
93
                    file_pid = atoi(p_filepid);
 
94
                    if (file_pid == (int)getpid()) {
 
95
                        if(unlink(addr_filename) == 0) {
 
96
                            LOG(log_info, logtype_afpd, "removed %s", addr_filename);
 
97
                        } else {
 
98
                            LOG(log_info, logtype_afpd, "error removing %s: %s",
 
99
                                    addr_filename, strerror(errno));
 
100
                        }
 
101
                    } else {
 
102
                        LOG(log_info, logtype_afpd, "%s belongs to another pid %d",
 
103
                             addr_filename, file_pid );
 
104
                    }
 
105
                } else { /* no pid info */
 
106
                    if (unlink(addr_filename) == 0) {
 
107
                        LOG(log_info, logtype_afpd, "removed %s", addr_filename );
 
108
                    } else {
 
109
                        LOG(log_info, logtype_afpd, "error removing %s: %s",
 
110
                                addr_filename, strerror(errno));
 
111
                    }
 
112
                }
 
113
            } else {
 
114
                LOG(log_info, logtype_afpd, "couldn't read data from %s", addr_filename );
 
115
            }
 
116
        } else {
 
117
            LOG(log_info, logtype_afpd, "%s is not a regular file", addr_filename );
 
118
        }
 
119
    } else {
 
120
        LOG(log_info, logtype_afpd, "error stat'ing %s: %s",
 
121
                   addr_filename, strerror(errno));
 
122
    }
 
123
}
 
124
 
 
125
static void afp_asp_die(const int sig)
 
126
{
 
127
    ASP asp = child->handle;
 
128
 
 
129
    asp_attention(asp, AFPATTN_SHUTDOWN);
 
130
    if ( asp_shutdown( asp ) < 0 ) {
 
131
        LOG(log_error, logtype_afpd, "afp_die: asp_shutdown: %s", strerror(errno) );
 
132
    }
 
133
 
 
134
    afp_asp_close(child);
 
135
    if (sig == SIGTERM || sig == SIGALRM)
 
136
        exit( 0 );
 
137
    else
 
138
        exit(sig);
 
139
}
 
140
 
 
141
static void afp_asp_timedown()
 
142
{
 
143
    struct sigaction    sv;
 
144
    struct itimerval    it;
 
145
 
 
146
    /* shutdown and don't reconnect. server going down in 5 minutes. */
 
147
    asp_attention(child->handle, AFPATTN_SHUTDOWN | AFPATTN_NORECONNECT |
 
148
                  AFPATTN_TIME(5));
 
149
 
 
150
    it.it_interval.tv_sec = 0;
 
151
    it.it_interval.tv_usec = 0;
 
152
    it.it_value.tv_sec = 300;
 
153
    it.it_value.tv_usec = 0;
 
154
    if ( setitimer( ITIMER_REAL, &it, 0 ) < 0 ) {
 
155
        LOG(log_error, logtype_afpd, "afp_timedown: setitimer: %s", strerror(errno) );
 
156
        afp_asp_die(1);
 
157
    }
 
158
 
 
159
    memset(&sv, 0, sizeof(sv));
 
160
    sv.sa_handler = afp_asp_die;
 
161
    sigemptyset( &sv.sa_mask );
 
162
    sv.sa_flags = SA_RESTART;
 
163
    if ( sigaction( SIGALRM, &sv, 0 ) < 0 ) {
 
164
        LOG(log_error, logtype_afpd, "afp_timedown: sigaction: %s", strerror(errno) );
 
165
        afp_asp_die(1);
 
166
    }
 
167
}
 
168
 
 
169
void afp_over_asp(AFPObj *obj)
 
170
{
 
171
    ASP asp;
 
172
    struct sigaction  action;
 
173
    int         func, ccnt = 0, reply = 0;
 
174
 
 
175
    obj->exit = afp_asp_die;
 
176
    obj->reply = (int (*)()) asp_cmdreply;
 
177
    obj->attention = (int (*)(void *, AFPUserBytes)) asp_attention;
 
178
    child = obj;
 
179
    asp = (ASP) obj->handle;
 
180
 
 
181
    /* install signal handlers */
 
182
    memset(&action, 0, sizeof(action));
 
183
    action.sa_handler = afp_asp_timedown;
 
184
    sigemptyset( &action.sa_mask );
 
185
    action.sa_flags = SA_RESTART;
 
186
    if ( sigaction( SIGHUP, &action, 0 ) < 0 ) {
 
187
        LOG(log_error, logtype_afpd, "afp_over_asp: sigaction: %s", strerror(errno) );
 
188
        afp_asp_die(1);
 
189
    }
 
190
 
 
191
    action.sa_handler = afp_asp_die;
 
192
    sigemptyset( &action.sa_mask );
 
193
    action.sa_flags = SA_RESTART;
 
194
    if ( sigaction( SIGTERM, &action, 0 ) < 0 ) {
 
195
        LOG(log_error, logtype_afpd, "afp_over_asp: sigaction: %s", strerror(errno) );
 
196
        afp_asp_die(1);
 
197
    }
 
198
 
 
199
    LOG(log_info, logtype_afpd, "session from %u.%u:%u on %u.%u:%u",
 
200
        ntohs( asp->asp_sat.sat_addr.s_net ),
 
201
        asp->asp_sat.sat_addr.s_node, asp->asp_sat.sat_port,
 
202
        ntohs( atp_sockaddr( asp->asp_atp )->sat_addr.s_net ),
 
203
        atp_sockaddr( asp->asp_atp )->sat_addr.s_node,
 
204
        atp_sockaddr( asp->asp_atp )->sat_port );
 
205
 
 
206
    while ((reply = asp_getrequest(asp))) {
 
207
        switch (reply) {
 
208
        case ASPFUNC_CLOSE :
 
209
            afp_asp_close(obj);
 
210
            LOG(log_info, logtype_afpd, "done" );
 
211
 
 
212
            if ( obj->options.flags & OPTION_DEBUG ) {
 
213
                printf( "done\n" );
 
214
            }
 
215
            return;
 
216
            break;
 
217
 
 
218
        case ASPFUNC_CMD :
 
219
#ifdef AFS
 
220
            if ( writtenfork ) {
 
221
                if ( flushfork( writtenfork ) < 0 ) {
 
222
                    LOG(log_error, logtype_afpd, "main flushfork: %s",
 
223
                                                strerror(errno));
 
224
                }
 
225
                writtenfork = NULL;
 
226
            }
 
227
#endif /* AFS */
 
228
            func = (u_char) asp->commands[0];
 
229
            if ( obj->options.flags & OPTION_DEBUG ) {
 
230
                printf("command: %d (%s)\n", func, AfpNum2name(func));
 
231
                bprint( asp->commands, asp->cmdlen );
 
232
            }
 
233
            if ( afp_switch[ func ] != NULL ) {
 
234
                /*
 
235
                 * The function called from afp_switch is expected to
 
236
                 * read its parameters out of buf, put its
 
237
                 * results in replybuf (updating rbuflen), and
 
238
                 * return an error code.
 
239
                */
 
240
                asp->datalen = ASP_DATASIZ;
 
241
                reply = (*afp_switch[ func ])(obj,
 
242
                                              asp->commands, asp->cmdlen,
 
243
                                              asp->data, &asp->datalen);
 
244
#ifdef FORCE_UIDGID
 
245
                /* bring everything back to old euid, egid */
 
246
                if (obj->force_uid)
 
247
                    restore_uidgid ( &obj->uidgid );
 
248
#endif /* FORCE_UIDGID */
 
249
            } else {
 
250
                LOG(log_error, logtype_afpd, "bad function %X", func );
 
251
                asp->datalen = 0;
 
252
                reply = AFPERR_NOOP;
 
253
            }
 
254
            if ( obj->options.flags & OPTION_DEBUG ) {
 
255
                printf( "reply: %d, %d\n", reply, ccnt++ );
 
256
                bprint( asp->data, asp->datalen );
 
257
            }
 
258
 
 
259
            if ( asp_cmdreply( asp, reply ) < 0 ) {
 
260
                LOG(log_error, logtype_afpd, "asp_cmdreply: %s", strerror(errno) );
 
261
                afp_asp_die(1);
 
262
            }
 
263
            break;
 
264
 
 
265
        case ASPFUNC_WRITE :
 
266
            func = (u_char) asp->commands[0];
 
267
            if ( obj->options.flags & OPTION_DEBUG ) {
 
268
                printf( "(write) command: %d\n", func );
 
269
                bprint( asp->commands, asp->cmdlen );
 
270
            }
 
271
            if ( afp_switch[ func ] != NULL ) {
 
272
                asp->datalen = ASP_DATASIZ;
 
273
                reply = (*afp_switch[ func ])(obj,
 
274
                                              asp->commands, asp->cmdlen,
 
275
                                              asp->data, &asp->datalen);
 
276
#ifdef FORCE_UIDGID
 
277
                /* bring everything back to old euid, egid */
 
278
                if (obj->force_uid)
 
279
                    restore_uidgid ( &obj->uidgid );
 
280
#endif /* FORCE_UIDGID */
 
281
            } else {
 
282
                LOG(log_error, logtype_afpd, "(write) bad function %X", func );
 
283
                asp->datalen = 0;
 
284
                reply = AFPERR_NOOP;
 
285
            }
 
286
            if ( obj->options.flags & OPTION_DEBUG ) {
 
287
                printf( "(write) reply code: %d, %d\n", reply, ccnt++ );
 
288
                bprint( asp->data, asp->datalen );
 
289
            }
 
290
            if ( asp_wrtreply( asp, reply ) < 0 ) {
 
291
                LOG(log_error, logtype_afpd, "asp_wrtreply: %s", strerror(errno) );
 
292
                afp_asp_die(1);
 
293
            }
 
294
            break;
 
295
        default:
 
296
            /*
 
297
               * Bad asp packet.  Probably should have asp filter them,
 
298
               * since they are typically things like out-of-order packet.
 
299
               */
 
300
            LOG(log_info, logtype_afpd, "main: asp_getrequest: %d", reply );
 
301
            break;
 
302
        }
 
303
 
 
304
        if ( obj->options.flags & OPTION_DEBUG ) {
 
305
#ifdef notdef
 
306
            pdesc( stdout );
 
307
#endif /* notdef */
 
308
            of_pforkdesc( stdout );
 
309
            fflush( stdout );
 
310
        }
 
311
    }
 
312
}
 
313
 
 
314
#endif