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 19static void dsi_init_buffer(DSI *dsi) 20{ 21 size_t quantum = dsi->server_quantum ? dsi->server_quantum : DSI_SERVQUANT_DEF; 22 23 /* default is 12 * 300k = 3,6 MB (Apr 2011) */ 24 if ((dsi->buffer = malloc(dsi->dsireadbuf * quantum)) == NULL) { 25 LOG(log_error, logtype_dsi, "dsi_init_buffer: OOM"); 26 AFP_PANIC("OOM in dsi_init_buffer"); 27 } 28 dsi->start = dsi->buffer; 29 dsi->eof = dsi->buffer; 30 dsi->end = dsi->buffer + (dsi->dsireadbuf * quantum); 31} 32 33/* OpenSession. set up the connection */ 34void dsi_opensession(DSI *dsi) 35{ 36 u_int32_t i = 0; /* this serves double duty. it must be 4-bytes long */ 37 int offs; 38 39 dsi_init_buffer(dsi); 40 if (setnonblock(dsi->socket, 1) < 0) { 41 LOG(log_error, logtype_dsi, "dsi_opensession: setnonblock: %s", strerror(errno)); 42 AFP_PANIC("setnonblock error"); 43 } 44 45 /* parse options */ 46 while (i < dsi->cmdlen) { 47 switch (dsi->commands[i++]) { 48 case DSIOPT_ATTNQUANT: 49 memcpy(&dsi->attn_quantum, dsi->commands + i + 1, dsi->commands[i]); 50 dsi->attn_quantum = ntohl(dsi->attn_quantum); 51 52 case DSIOPT_SERVQUANT: /* just ignore these */ 53 default: 54 i += dsi->commands[i] + 1; /* forward past length tag + length */ 55 break; 56 } 57 } 58 59 /* let the client know the server quantum. we don't use the 60 * max server quantum due to a bug in appleshare client 3.8.6. */ 61 dsi->header.dsi_flags = DSIFL_REPLY; 62 dsi->header.dsi_code = 0; 63 /* dsi->header.dsi_command = DSIFUNC_OPEN;*/ 64 65 dsi->cmdlen = 2 * (2 + sizeof(i)); /* length of data. dsi_send uses it. */ 66 67 /* DSI Option Server Request Quantum */ 68 dsi->commands[0] = DSIOPT_SERVQUANT; 69 dsi->commands[1] = sizeof(i); 70 i = htonl(( dsi->server_quantum < DSI_SERVQUANT_MIN || 71 dsi->server_quantum > DSI_SERVQUANT_MAX ) ? 72 DSI_SERVQUANT_DEF : dsi->server_quantum); 73 memcpy(dsi->commands + 2, &i, sizeof(i)); 74 75 /* AFP replaycache size option */ 76 offs = 2 + sizeof(i); 77 dsi->commands[offs] = DSIOPT_REPLCSIZE; 78 dsi->commands[offs+1] = sizeof(i); 79 i = htonl(REPLAYCACHE_SIZE); 80 memcpy(dsi->commands + offs + 2, &i, sizeof(i)); 81 dsi_send(dsi); 82} 83