r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text
[bbaumbach/samba-autobuild/.git] / source3 / smbd / message.c
1 /* 
2    Unix SMB/CIFS implementation.
3    SMB messaging
4    Copyright (C) Andrew Tridgell 1992-1998
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 /*
20    This file handles the messaging system calls for winpopup style
21    messages
22 */
23
24
25 #include "includes.h"
26
27 extern userdom_struct current_user_info;
28
29 /* look in server.c for some explanation of these variables */
30 static char msgbuf[1600];
31 static int msgpos;
32 static fstring msgfrom;
33 static fstring msgto;
34
35 /****************************************************************************
36  Deliver the message.
37 ****************************************************************************/
38
39 static void msg_deliver(void)
40 {
41         pstring name;
42         int i;
43         int fd;
44         char *msg;
45         int len;
46         ssize_t sz;
47
48         if (! (*lp_msg_command())) {
49                 DEBUG(1,("no messaging command specified\n"));
50                 msgpos = 0;
51                 return;
52         }
53
54         /* put it in a temporary file */
55         slprintf(name,sizeof(name)-1, "%s/msg.XXXXXX",tmpdir());
56         fd = smb_mkstemp(name);
57
58         if (fd == -1) {
59                 DEBUG(1,("can't open message file %s\n",name));
60                 return;
61         }
62
63         /*
64          * Incoming message is in DOS codepage format. Convert to UNIX.
65          */
66   
67         if ((len = (int)convert_string_allocate(NULL,CH_DOS, CH_UNIX, msgbuf, msgpos, (void **)(void *)&msg, True)) < 0 || !msg) {
68                 DEBUG(3,("Conversion failed, delivering message in DOS codepage format\n"));
69                 for (i = 0; i < msgpos;) {
70                         if (msgbuf[i] == '\r' && i < (msgpos-1) && msgbuf[i+1] == '\n') {
71                                 i++;
72                                 continue;
73                         }
74                         sz = write(fd, &msgbuf[i++], 1);
75                         if ( sz != 1 ) {
76                                 DEBUG(0,("Write error to fd %d: %ld(%d)\n",fd, (long)sz, errno ));
77                         }
78                 }
79         } else {
80                 for (i = 0; i < len;) {
81                         if (msg[i] == '\r' && i < (len-1) && msg[i+1] == '\n') {
82                                 i++;
83                                 continue;
84                         }
85                         sz = write(fd, &msg[i++],1);
86                         if ( sz != 1 ) {
87                                 DEBUG(0,("Write error to fd %d: %ld(%d)\n",fd, (long)sz, errno ));
88                         }
89                 }
90                 SAFE_FREE(msg);
91         }
92         close(fd);
93
94         /* run the command */
95         if (*lp_msg_command()) {
96                 fstring alpha_msgfrom;
97                 fstring alpha_msgto;
98                 pstring s;
99
100                 pstrcpy(s,lp_msg_command());
101                 pstring_sub(s,"%f",alpha_strcpy(alpha_msgfrom,msgfrom,NULL,sizeof(alpha_msgfrom)));
102                 pstring_sub(s,"%t",alpha_strcpy(alpha_msgto,msgto,NULL,sizeof(alpha_msgto)));
103                 standard_sub_basic(current_user_info.smb_name,
104                                 current_user_info.domain, s, sizeof(s));
105                 pstring_sub(s,"%s",name);
106                 smbrun(s,NULL);
107         }
108
109         msgpos = 0;
110 }
111
112 /****************************************************************************
113  Reply to a sends.
114  conn POINTER CAN BE NULL HERE !
115 ****************************************************************************/
116
117 int reply_sends(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
118 {
119         int len;
120         char *msg;
121         int outsize = 0;
122         char *p;
123
124         START_PROFILE(SMBsends);
125
126         msgpos = 0;
127
128         if (! (*lp_msg_command())) {
129                 END_PROFILE(SMBsends);
130                 return(ERROR_DOS(ERRSRV,ERRmsgoff));
131         }
132
133         outsize = set_message(inbuf,outbuf,0,0,True);
134
135         p = smb_buf(inbuf)+1;
136         p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), msgfrom, p,
137                              sizeof(msgfrom), STR_ASCII|STR_TERMINATE) + 1;
138         p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), msgto, p,
139                              sizeof(msgto), STR_ASCII|STR_TERMINATE) + 1;
140
141         msg = p;
142
143         len = SVAL(msg,0);
144         len = MIN(len,sizeof(msgbuf)-msgpos);
145
146         memset(msgbuf,'\0',sizeof(msgbuf));
147
148         memcpy(&msgbuf[msgpos],msg+2,len);
149         msgpos += len;
150
151         msg_deliver();
152
153         END_PROFILE(SMBsends);
154         return(outsize);
155 }
156
157 /****************************************************************************
158  Reply to a sendstrt.
159  conn POINTER CAN BE NULL HERE !
160 ****************************************************************************/
161
162 int reply_sendstrt(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
163 {
164         int outsize = 0;
165         char *p;
166
167         START_PROFILE(SMBsendstrt);
168
169         if (! (*lp_msg_command())) {
170                 END_PROFILE(SMBsendstrt);
171                 return(ERROR_DOS(ERRSRV,ERRmsgoff));
172         }
173
174         outsize = set_message(inbuf,outbuf,1,0,True);
175
176         memset(msgbuf,'\0',sizeof(msgbuf));
177         msgpos = 0;
178
179         p = smb_buf(inbuf)+1;
180         p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), msgfrom, p,
181                              sizeof(msgfrom), STR_ASCII|STR_TERMINATE) + 1;
182         p += srvstr_pull_buf(inbuf, SVAL(inbuf, smb_flg2), msgto, p,
183                              sizeof(msgto), STR_ASCII|STR_TERMINATE) + 1;
184
185         DEBUG( 3, ( "SMBsendstrt (from %s to %s)\n", msgfrom, msgto ) );
186
187         END_PROFILE(SMBsendstrt);
188         return(outsize);
189 }
190
191 /****************************************************************************
192  Reply to a sendtxt.
193  conn POINTER CAN BE NULL HERE !
194 ****************************************************************************/
195
196 int reply_sendtxt(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
197 {
198         int len;
199         int outsize = 0;
200         char *msg;
201         START_PROFILE(SMBsendtxt);
202
203         if (! (*lp_msg_command())) {
204                 END_PROFILE(SMBsendtxt);
205                 return(ERROR_DOS(ERRSRV,ERRmsgoff));
206         }
207
208         outsize = set_message(inbuf,outbuf,0,0,True);
209
210         msg = smb_buf(inbuf) + 1;
211
212         len = SVAL(msg,0);
213         len = MIN(len,sizeof(msgbuf)-msgpos);
214
215         memcpy(&msgbuf[msgpos],msg+2,len);
216         msgpos += len;
217
218         DEBUG( 3, ( "SMBsendtxt\n" ) );
219
220         END_PROFILE(SMBsendtxt);
221         return(outsize);
222 }
223
224 /****************************************************************************
225  Reply to a sendend.
226  conn POINTER CAN BE NULL HERE !
227 ****************************************************************************/
228
229 int reply_sendend(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
230 {
231         int outsize = 0;
232         START_PROFILE(SMBsendend);
233
234         if (! (*lp_msg_command())) {
235                 END_PROFILE(SMBsendend);
236                 return(ERROR_DOS(ERRSRV,ERRmsgoff));
237         }
238
239         outsize = set_message(inbuf,outbuf,0,0,True);
240
241         DEBUG(3,("SMBsendend\n"));
242
243         msg_deliver();
244
245         END_PROFILE(SMBsendend);
246         return(outsize);
247 }