X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fmessages.c;h=e48585e353b1d2ab4dff76cc3ebb46812853a8ca;hb=b0bcb8f6b0571592a50ce039882c9319e012a270;hp=c723211ae1936901dca5fca57586ac81d6205b18;hpb=f291e1ee2d32891f4f451e946b5894a038ed8c48;p=netatalk.git diff --git a/etc/afpd/messages.c b/etc/afpd/messages.c index c723211a..e48585e3 100644 --- a/etc/afpd/messages.c +++ b/etc/afpd/messages.c @@ -1,6 +1,4 @@ /* - * $Id: messages.c,v 1.16 2002-03-24 01:23:41 sibaz Exp $ - * * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu) * All Rights Reserved. See COPYRIGHT. */ @@ -9,49 +7,61 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ +#include #include #include #include +#include #include +#include +#include #include -#ifdef HAVE_UNISTD_H -#include -#endif /* HAVE_UNISTD_H */ -#include "globals.h" +#include + #include "misc.h" + #define MAXMESGSIZE 199 /* this is only used by afpd children, so it's okay. */ -static char servermesg[MAXMESGSIZE] = ""; +static char servermesg[MAXPATHLEN] = ""; +static char localized_message[MAXPATHLEN] = ""; void setmessage(const char *message) { - strncpy(servermesg, message, MAXMESGSIZE); + strlcpy(servermesg, message, MAXMESGSIZE); } -void readmessage(void) +void readmessage(AFPObj *obj) { /* Read server message from file defined as SERVERTEXT */ #ifdef SERVERTEXT FILE *message; char * filename; - int i, rc; + unsigned int i; + int rc; static int c; uid_t euid; + u_int32_t maxmsgsize; + + maxmsgsize = (obj->proto == AFPPROTO_DSI)?MIN(MAX(((DSI*)obj->handle)->attn_quantum, MAXMESGSIZE),MAXPATHLEN):MAXMESGSIZE; i=0; /* Construct file name SERVERTEXT/message.[pid] */ - filename=malloc(sizeof(SERVERTEXT)+15); + if ( NULL == (filename=(char*) malloc(sizeof(SERVERTEXT)+15)) ) { + LOG(log_error, logtype_afpd, "readmessage: malloc: %s", strerror(errno) ); + return; + } + sprintf(filename, "%s/message.%d", SERVERTEXT, getpid()); #ifdef DEBUG - LOG(log_debug, logtype_afpd, "Reading file %s ", filename); -#endif /* DEBUG */ + LOG(log_debug9, logtype_afpd, "Reading file %s ", filename); +#endif message=fopen(filename, "r"); if (message==NULL) { - LOG(log_info, logtype_afpd, "Unable to open file %s", filename); + /* try without the process id */ sprintf(filename, "%s/message", SERVERTEXT); message=fopen(filename, "r"); } @@ -59,7 +69,7 @@ void readmessage(void) /* if either message.pid or message exists */ if (message!=NULL) { /* added while loop to get characters and put in servermesg */ - while ((( c=fgetc(message)) != EOF) && (i < (MAXMESGSIZE - 1))) { + while ((( c=fgetc(message)) != EOF) && (i < (maxmsgsize - 1))) { if ( c == '\n') c = ' '; servermesg[i++] = c; } @@ -76,11 +86,13 @@ void readmessage(void) strerror(errno)); } - rc = unlink(filename); + if ((rc = unlink(filename)) != 0) + LOG(log_error, logtype_afpd, "File '%s' could not be deleted", strerror(errno)); /* Drop privs again, failing this is very bad */ if (seteuid(euid) < 0) { LOG(log_error, logtype_afpd, "Could not switch back to uid %d: %s", euid, strerror(errno)); + exit(EXITERR_SYS); } if (rc < 0) { @@ -88,56 +100,93 @@ void readmessage(void) } #ifdef DEBUG else { - LOG(log_info, logtype_afpd, "Deleted %s", filename); + LOG(log_debug9, logtype_afpd, "Deleted %s", filename); } - LOG(log_info, logtype_afpd, "Set server message to \"%s\"", servermesg); -#endif /* DEBUG */ + LOG(log_debug9, logtype_afpd, "Set server message to \"%s\"", servermesg); +#endif } free(filename); #endif /* SERVERTEXT */ } -int afp_getsrvrmesg(obj, ibuf, ibuflen, rbuf, rbuflen) -AFPObj *obj; -char *ibuf, *rbuf; -int ibuflen, *rbuflen; +int afp_getsrvrmesg(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) { char *message; u_int16_t type, bitmap; + u_int16_t msgsize; + size_t outlen = 0; + size_t msglen = 0; + int utf8 = 0; + + *rbuflen = 0; + + msgsize = (obj->proto == AFPPROTO_DSI)?MAX(((DSI*)obj->handle)->attn_quantum, MAXMESGSIZE):MAXMESGSIZE; memcpy(&type, ibuf + 2, sizeof(type)); memcpy(&bitmap, ibuf + 4, sizeof(bitmap)); + message = servermesg; switch (ntohs(type)) { case AFPMESG_LOGIN: /* login */ - message = obj->options.loginmesg; + /* at least TIGER loses server messages + * if it receives a server msg attention before + * it has asked the login msg... + * Workaround: concatenate the two if any, ugly. + */ + if (*message && *obj->options.loginmesg) { + strlcat(message, " - ", MAXMESGSIZE); + } + strlcat(message, obj->options.loginmesg, MAXMESGSIZE); break; case AFPMESG_SERVER: /* server */ - message = servermesg; break; default: - *rbuflen = 0; return AFPERR_BITMAP; } /* output format: * message type: 2 bytes * bitmap: 2 bytes - * message length: 1 byte - * message: up to 199 bytes + * message length: 1 byte ( 2 bytes for utf8) + * message: up to 199 bytes (dsi attn_quantum for utf8) */ memcpy(rbuf, &type, sizeof(type)); rbuf += sizeof(type); + *rbuflen += sizeof(type); memcpy(rbuf, &bitmap, sizeof(bitmap)); rbuf += sizeof(bitmap); - *rbuflen = strlen(message); - if (*rbuflen > MAXMESGSIZE) - *rbuflen = MAXMESGSIZE; - *rbuf++ = *rbuflen; - memcpy(rbuf, message, *rbuflen); - - *rbuflen += 5; - + *rbuflen += sizeof(bitmap); + + utf8 = ntohs(bitmap) & 2; + msglen = strlen(message); + if (msglen > msgsize) + msglen = msgsize; + + if (msglen) { + if ( (size_t)-1 == (outlen = convert_string(obj->options.unixcharset, utf8?CH_UTF8_MAC:obj->options.maccharset, + message, msglen, localized_message, msgsize)) ) + { + memcpy(rbuf+((utf8)?2:1), message, msglen); /*FIXME*/ + outlen = msglen; + } + else + { + memcpy(rbuf+((utf8)?2:1), localized_message, outlen); + } + } + + if ( utf8 ) { + /* UTF8 message, 2 byte length */ + msgsize = htons(outlen); + memcpy(rbuf, &msgsize, sizeof(msgsize)); + *rbuflen += sizeof(msgsize); + } + else { + *rbuf = outlen; + *rbuflen += 1; + } + *rbuflen += outlen; + *message = 0; return AFP_OK; }