X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=blobdiff_plain;f=etc%2Fafpd%2Fstatus.c;h=745d349c5765768ce49960dfbd121312d55f97a0;hp=92642c8ba74897e2e8f992988b625c4722110767;hb=75fe310224dffb96868d7f2cb1ec9125a84f2a08;hpb=d8736f77764e18812d1c05769bd211b56539d1c1 diff --git a/etc/afpd/status.c b/etc/afpd/status.c index 92642c8b..745d349c 100644 --- a/etc/afpd/status.c +++ b/etc/afpd/status.c @@ -1,5 +1,5 @@ /* - * $Id: status.c,v 1.17 2005-05-03 14:55:10 didg Exp $ + * $Id: status.c,v 1.27 2009-11-05 14:38:07 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -18,9 +18,9 @@ #ifdef BSD4_4 #include -#ifndef USE_GETHOSTID +#ifndef HAVE_GETHOSTID #include -#endif /* USE_GETHOSTID */ +#endif /* HAVE_GETHOSTID */ #endif /* BSD4_4 */ #include @@ -39,7 +39,7 @@ static size_t maxstatuslen = 0; static void status_flags(char *data, const int notif, const int ipok, - const unsigned char passwdbits, const int dirsrvcs _U_) + const unsigned char passwdbits, const int dirsrvcs _U_, int flags) { u_int16_t status; @@ -65,6 +65,9 @@ static void status_flags(char *data, const int notif, const int ipok, status |= AFPSRVRINFO_SRVRDIR; /* AFP 3.1 specs says we need to specify this, but may set the count to 0 */ /* We don't set the UTF8 name flag here, we don't know whether we have enough space ... */ + if (flags & OPTION_UUID) /* 05122008 FIXME: can we set AFPSRVRINFO_UUID here ? see AFPSRVRINFO_SRVRDIR*/ + status |= AFPSRVRINFO_UUID; + status = htons(status); memcpy(data + AFPSTATUS_FLAGOFF, &status, sizeof(status)); } @@ -85,7 +88,7 @@ static int status_server(char *data, const char *server, const struct afp_option nbp_name(server, &Obj, &Type, &Zone); if ((size_t)-1 == (len = convert_string( options->unixcharset, options->maccharset, - Obj, strlen(Obj), buf, 31)) ) { + Obj, -1, buf, sizeof(buf))) ) { len = MIN(strlen(Obj), 31); *data++ = len; memcpy( data, Obj, len ); @@ -191,18 +194,24 @@ static u_int16_t status_signature(char *data, int *servoffset, DSI *dsi, /* If signature type is a standard hostid... */ server_signature_hostid: /* 16-byte signature consists of copies of the hostid */ -#if defined(BSD4_4) && defined(USE_GETHOSTID) +#if defined(BSD4_4) && !defined(HAVE_GETHOSTID) mib[0] = CTL_KERN; mib[1] = KERN_HOSTID; len = sizeof(hostid); sysctl(mib, 2, &hostid, &len, NULL, 0); -#else /* BSD4_4 && USE_GETHOSTID */ +#else /* BSD4_4 && !HAVE_GETHOSTID */ hostid = gethostid(); -#endif /* BSD4_4 && USE_GETHOSTID */ +#endif /* BSD4_4 && !HAVE_GETHOSTID */ if (!hostid) { - if (dsi) - hostid = dsi->server.sin_addr.s_addr; - else { + if (dsi) { + if (dsi->server.ss_family == AF_INET) { /* IPv4 */ + hostid = ((struct sockaddr_in *)(&dsi->server))->sin_addr.s_addr; + } else { /* IPv6 */ + struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&dsi->server; + /* Use the last "sizeof(long) bytes of the IPv6 addr */ + memcpy(&hostid, sa6->sin6_addr.s6_addr + (16 - sizeof(long)), sizeof(long)); + } + } else { struct hostent *host; if ((host = gethostbyname(options->hostname))) @@ -258,25 +267,45 @@ static size_t status_netaddress(char *data, int *servoffset, /* ip address */ if (dsi) { - const struct sockaddr_in *inaddr = &dsi->server; - - if (inaddr->sin_port == htons(DSI_AFPOVERTCP_PORT)) { - *data++ = 6; /* length */ - *data++ = 0x01; /* basic ip address */ - memcpy(data, &inaddr->sin_addr.s_addr, - sizeof(inaddr->sin_addr.s_addr)); - data += sizeof(inaddr->sin_addr.s_addr); - addresses_len += 7; - } else { - /* ip address + port */ - *data++ = 8; - *data++ = 0x02; /* ip address with port */ - memcpy(data, &inaddr->sin_addr.s_addr, - sizeof(inaddr->sin_addr.s_addr)); - data += sizeof(inaddr->sin_addr.s_addr); - memcpy(data, &inaddr->sin_port, sizeof(inaddr->sin_port)); - data += sizeof(inaddr->sin_port); - addresses_len += 9; + if (dsi->server.ss_family == AF_INET) { /* IPv4 */ + const struct sockaddr_in *inaddr = (struct sockaddr_in *)&dsi->server; + if (inaddr->sin_port == htons(DSI_AFPOVERTCP_PORT)) { + *data++ = 6; /* length */ + *data++ = 0x01; /* basic ip address */ + memcpy(data, &inaddr->sin_addr.s_addr, + sizeof(inaddr->sin_addr.s_addr)); + data += sizeof(inaddr->sin_addr.s_addr); + addresses_len += 7; + } else { + /* ip address + port */ + *data++ = 8; + *data++ = 0x02; /* ip address with port */ + memcpy(data, &inaddr->sin_addr.s_addr, + sizeof(inaddr->sin_addr.s_addr)); + data += sizeof(inaddr->sin_addr.s_addr); + memcpy(data, &inaddr->sin_port, sizeof(inaddr->sin_port)); + data += sizeof(inaddr->sin_port); + addresses_len += 9; + } + } else { /* IPv6 */ + const struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&dsi->server; + if (sa6->sin6_port == htons(DSI_AFPOVERTCP_PORT)) { + *data++ = 18; /* length */ + *data++ = 6; /* type */ + memcpy(data, &sa6->sin6_addr.s6_addr, sizeof(sa6->sin6_addr.s6_addr)); + data += sizeof(sa6->sin6_addr.s6_addr); + addresses_len += 19; + } else { + /* ip address + port */ + *data++ = 20; /* length */ + *data++ = 7; /* type*/ + memcpy(data, &sa6->sin6_addr.s6_addr, sizeof(sa6->sin6_addr.s6_addr)); + data += sizeof(sa6->sin6_addr.s6_addr); + memcpy(data, &sa6->sin6_port, sizeof(sa6->sin6_port)); + data += sizeof(sa6->sin6_port); + addresses_len += 21; + } + } } @@ -414,7 +443,7 @@ static size_t status_utf8servername(char *data, int *nameoffset, if ((size_t) -1 == (len = convert_string ( options->unixcharset, CH_UTF8_MAC, - Obj, strlen(Obj), data+sizeof(namelen), maxstatuslen-offset )) ) { + Obj, -1, data+sizeof(namelen), maxstatuslen-offset )) ) { LOG ( log_error, logtype_afpd, "Could not set utf8 servername"); /* set offset to 0 */ @@ -468,7 +497,7 @@ static void status_icon(char *data, const unsigned char *icondata, /* --------------------- */ -void status_reset() +void status_reset(void) { Id = 0; } @@ -483,7 +512,7 @@ void status_init(AFPConfig *aspconfig, AFPConfig *dsiconfig, DSI *dsi; char *status = NULL; size_t statuslen; - int c, sigoff; + int c, sigoff, ipok; if (!(aspconfig || dsiconfig) || !options) return; @@ -499,6 +528,19 @@ void status_init(AFPConfig *aspconfig, AFPConfig *dsiconfig, status = dsiconfig->status; maxstatuslen=sizeof(dsiconfig->status); dsi = dsiconfig->obj.handle; + if (dsi->server.ss_family == AF_INET) { /* IPv4 */ + const struct sockaddr_in *sa4 = (struct sockaddr_in *)&dsi->server; + ipok = sa4->sin_addr.s_addr ? 1 : 0; + } else { /* IPv6 */ + const struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)&dsi->server; + ipok = 0; + for (int i=0; i<16; i++) { + if (sa6->sin6_addr.s6_addr[i]) { + ipok = 1; + break; + } + } + } } else dsi = NULL; @@ -522,10 +564,12 @@ void status_init(AFPConfig *aspconfig, AFPConfig *dsiconfig, * (16-bytes), network addresses, volume icon/mask */ - status_flags(status, options->server_notif, options->fqdn || - (dsiconfig && dsi->server.sin_addr.s_addr), + status_flags(status, + options->server_notif, + (options->fqdn || ipok), options->passwdbits, - (options->k5service && options->k5realm && options->fqdn)); + (options->k5service && options->k5realm && options->fqdn), + options->flags); /* returns offset to signature offset */ c = status_server(status, options->server ? options->server : options->hostname, options); @@ -570,10 +614,7 @@ void status_init(AFPConfig *aspconfig, AFPConfig *dsiconfig, } /* this is the same as asp/dsi_getstatus */ -int afp_getsrvrinfo(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf _U_, *rbuf; -int ibuflen _U_, *rbuflen; +int afp_getsrvrinfo(AFPObj *obj, char *ibuf _U_, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) { AFPConfig *config = obj->config;