]> arthur.barton.de Git - netatalk.git/blob - libatalk/dsi/dsi_opensess.c
d01e64c42fb017c2b6ec94eab1283ff8d7ef22d6
[netatalk.git] / libatalk / dsi / dsi_opensess.c
1 /*
2  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
3  * All rights reserved. See COPYRIGHT.
4  */
5
6 #ifdef HAVE_CONFIG_H
7 #include "config.h"
8 #endif /* HAVE_CONFIG_H */
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <sys/types.h>
13 #include <stdlib.h>
14
15 #include <atalk/dsi.h>
16 #include <atalk/util.h>
17 #include <atalk/logger.h>
18
19 static void dsi_init_buffer(DSI *dsi)
20 {
21     /* default is 12 * 300k = 3,6 MB (Apr 2011) */
22     if ((dsi->buffer = malloc(dsi->dsireadbuf * dsi->server_quantum)) == NULL) {
23         LOG(log_error, logtype_dsi, "dsi_init_buffer: OOM");
24         AFP_PANIC("OOM in dsi_init_buffer");
25     }
26     dsi->start = dsi->buffer;
27     dsi->eof = dsi->buffer;
28     dsi->end = dsi->buffer + (dsi->dsireadbuf * dsi->server_quantum);
29 }
30
31 /* OpenSession. set up the connection */
32 void dsi_opensession(DSI *dsi)
33 {
34   uint32_t i = 0; /* this serves double duty. it must be 4-bytes long */
35   int offs;
36
37   dsi_init_buffer(dsi);
38   if (setnonblock(dsi->socket, 1) < 0) {
39       LOG(log_error, logtype_dsi, "dsi_opensession: setnonblock: %s", strerror(errno));
40       AFP_PANIC("setnonblock error");
41   }
42
43   /* parse options */
44   while (i < dsi->cmdlen) {
45     switch (dsi->commands[i++]) {
46     case DSIOPT_ATTNQUANT:
47       memcpy(&dsi->attn_quantum, dsi->commands + i + 1, dsi->commands[i]);
48       dsi->attn_quantum = ntohl(dsi->attn_quantum);
49
50     case DSIOPT_SERVQUANT: /* just ignore these */
51     default:
52       i += dsi->commands[i] + 1; /* forward past length tag + length */
53       break;
54     }
55   }
56
57   /* let the client know the server quantum. we don't use the
58    * max server quantum due to a bug in appleshare client 3.8.6. */
59   dsi->header.dsi_flags = DSIFL_REPLY;
60   dsi->header.dsi_code = 0;
61   /* dsi->header.dsi_command = DSIFUNC_OPEN;*/
62
63   dsi->cmdlen = 2 * (2 + sizeof(i)); /* length of data. dsi_send uses it. */
64
65   /* DSI Option Server Request Quantum */
66   dsi->commands[0] = DSIOPT_SERVQUANT;
67   dsi->commands[1] = sizeof(i);
68   i = htonl(( dsi->server_quantum < DSI_SERVQUANT_MIN || 
69               dsi->server_quantum > DSI_SERVQUANT_MAX ) ? 
70             DSI_SERVQUANT_DEF : dsi->server_quantum);
71   memcpy(dsi->commands + 2, &i, sizeof(i));
72
73   /* AFP replaycache size option */
74   offs = 2 + sizeof(i);
75   dsi->commands[offs] = DSIOPT_REPLCSIZE;
76   dsi->commands[offs+1] = sizeof(i);
77   i = htonl(REPLAYCACHE_SIZE);
78   memcpy(dsi->commands + offs + 2, &i, sizeof(i));
79   dsi_send(dsi);
80 }