]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/messages.c
merged patch #416371 from Heath Kehoe (hkehoe@users.sourceforge.net),
[netatalk.git] / etc / afpd / messages.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
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <atalk/afp.h>
13 #include <syslog.h>
14 #include <unistd.h>
15 #include "globals.h"
16 #include "misc.h"
17
18 #define MAXMESGSIZE 199
19
20 /* this is only used by afpd children, so it's okay. */
21 static char servermesg[MAXMESGSIZE] = "";
22
23 void setmessage(const char *message)
24 {
25   strncpy(servermesg, message, MAXMESGSIZE);
26 }
27
28 void readmessage(void)
29 {
30 /* Read server message from file defined as SERVERTEXT */
31 #ifdef SERVERTEXT
32   FILE *message;
33   char * filename;
34   int i, rc;
35   static int c;
36   uid_t euid;
37
38   i=0;
39   // Construct file name SERVERTEXT/message.[pid]
40   filename=malloc(sizeof(SERVERTEXT)+15);
41   sprintf(filename, "%s/message.%d", SERVERTEXT, getpid());
42
43 #ifdef DEBUG
44   syslog (LOG_DEBUG, "Reading file %s ", filename);
45 #endif
46   
47   message=fopen(filename, "r");
48   if (message==NULL) {
49     syslog (LOG_INFO, "Unable to open file %s", filename);
50     sprintf(filename, "%s/message", SERVERTEXT);
51     message=fopen(filename, "r");
52   }
53
54   /* if either message.pid or message exists */
55   if (message!=NULL) {
56     /* added while loop to get characters and put in servermesg */
57     while ((( c=fgetc(message)) != EOF) && (i < (MAXMESGSIZE - 1))) {
58       if ( c == '\n')  c = ' ';
59       servermesg[i++] = c;
60       }
61     servermesg[i] = 0;
62
63     /* cleanup */
64     fclose(message);
65
66     /* Save effective uid and switch to root to delete file. */
67     /* Delete will probably fail otherwise, but let's try anyways */
68     euid = geteuid();
69     if (seteuid(0) < 0) {
70       syslog(LOG_ERR, "Could not switch back to root: %m");
71     }
72
73     rc = unlink(filename);
74
75     /* Drop privs again, failing this is very bad */
76     if (seteuid(euid) < 0) {
77       syslog(LOG_ERR, "Could not switch back to uid %d: %m", euid);
78     }
79
80     if (rc < 0) {
81       syslog (LOG_ERR, "Error deleting %s: %m", filename);
82     }
83 #ifdef DEBUG
84     else {
85       syslog (LOG_INFO, "Deleted %s", filename);
86     }
87
88     syslog (LOG_INFO, "Set server message to \"%s\"", servermesg);
89 #endif
90   }
91   free(filename);
92 #endif
93 }
94
95 int afp_getsrvrmesg(obj, ibuf, ibuflen, rbuf, rbuflen)
96      AFPObj *obj;
97      char *ibuf, *rbuf;
98      int ibuflen, *rbuflen;
99 {
100   char *message;
101   u_int16_t type, bitmap;
102
103   memcpy(&type, ibuf + 2, sizeof(type));
104   memcpy(&bitmap, ibuf + 4, sizeof(bitmap));
105
106   switch (ntohs(type)) {
107   case AFPMESG_LOGIN: /* login */
108     message = obj->options.loginmesg;
109     break;
110   case AFPMESG_SERVER: /* server */
111     message = servermesg;
112     break;
113   default:
114     *rbuflen = 0;
115     return AFPERR_BITMAP;
116   }
117
118   /* output format:
119    * message type:   2 bytes
120    * bitmap:         2 bytes
121    * message length: 1 byte
122    * message:        up to 199 bytes
123    */
124   memcpy(rbuf, &type, sizeof(type));
125   rbuf += sizeof(type);
126   memcpy(rbuf, &bitmap, sizeof(bitmap));
127   rbuf += sizeof(bitmap);
128   *rbuflen = strlen(message);
129   if (*rbuflen > MAXMESGSIZE)
130     *rbuflen = MAXMESGSIZE;
131   *rbuf++ = *rbuflen;
132   memcpy(rbuf, message, *rbuflen);
133
134   *rbuflen += 5;
135
136   return AFP_OK;
137 }