/* Unix SMB/CIFS implementation. SMB messaging Copyright (C) Andrew Tridgell 1992-1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* This file handles the messaging system calls for winpopup style messages */ #include "includes.h" extern userdom_struct current_user_info; /* look in server.c for some explanation of these variables */ static char msgbuf[1600]; static int msgpos; static fstring msgfrom; static fstring msgto; /**************************************************************************** Deliver the message. ****************************************************************************/ static void msg_deliver(void) { TALLOC_CTX *ctx = talloc_tos(); char *name = NULL; int i; int fd; char *msg; int len; ssize_t sz; if (! (*lp_msg_command())) { DEBUG(1,("no messaging command specified\n")); msgpos = 0; return; } /* put it in a temporary file */ name = talloc_asprintf(ctx, "%s/msg.XXXXXX",tmpdir()); if (!name) { return; } fd = smb_mkstemp(name); if (fd == -1) { DEBUG(1,("can't open message file %s\n",name)); return; } /* * Incoming message is in DOS codepage format. Convert to UNIX. */ if ((len = (int)convert_string_allocate(NULL,CH_DOS, CH_UNIX, msgbuf, msgpos, (void **)(void *)&msg, True)) < 0 || !msg) { DEBUG(3,("Conversion failed, delivering message in DOS codepage format\n")); for (i = 0; i < msgpos;) { if (msgbuf[i] == '\r' && i < (msgpos-1) && msgbuf[i+1] == '\n') { i++; continue; } sz = write(fd, &msgbuf[i++], 1); if ( sz != 1 ) { DEBUG(0,("Write error to fd %d: %ld(%d)\n",fd, (long)sz, errno )); } } } else { for (i = 0; i < len;) { if (msg[i] == '\r' && i < (len-1) && msg[i+1] == '\n') { i++; continue; } sz = write(fd, &msg[i++],1); if ( sz != 1 ) { DEBUG(0,("Write error to fd %d: %ld(%d)\n",fd, (long)sz, errno )); } } SAFE_FREE(msg); } close(fd); /* run the command */ if (*lp_msg_command()) { fstring alpha_msgfrom; fstring alpha_msgto; char *s = talloc_strdup(ctx, lp_msg_command()); if (!s) { return; } s = talloc_string_sub(ctx, s, "%f", alpha_strcpy(alpha_msgfrom, msgfrom, NULL, sizeof(alpha_msgfrom))); if (!s) { return; } s = talloc_string_sub(ctx, s, "%t", alpha_strcpy(alpha_msgto, msgto, NULL, sizeof(alpha_msgto))); if (!s) { return; } s = talloc_sub_basic(ctx, current_user_info.smb_name, current_user_info.domain, s); if (!s) { return; } s = talloc_string_sub(ctx, s, "%s",name); if (!s) { return; } smbrun(s,NULL); } msgpos = 0; } /**************************************************************************** Reply to a sends. conn POINTER CAN BE NULL HERE ! ****************************************************************************/ void reply_sends(connection_struct *conn, struct smb_request *req) { int len; char *msg; char *p; START_PROFILE(SMBsends); msgpos = 0; if (! (*lp_msg_command())) { reply_doserror(req, ERRSRV, ERRmsgoff); END_PROFILE(SMBsends); return; } p = smb_buf(req->inbuf)+1; p += srvstr_pull_buf((char *)req->inbuf, req->flags2, msgfrom, p, sizeof(msgfrom), STR_ASCII|STR_TERMINATE) + 1; p += srvstr_pull_buf((char *)req->inbuf, req->flags2, msgto, p, sizeof(msgto), STR_ASCII|STR_TERMINATE) + 1; msg = p; len = SVAL(msg,0); len = MIN(len,sizeof(msgbuf)-msgpos); memset(msgbuf,'\0',sizeof(msgbuf)); memcpy(&msgbuf[msgpos],msg+2,len); msgpos += len; msg_deliver(); reply_outbuf(req, 0, 0); END_PROFILE(SMBsends); return; } /**************************************************************************** Reply to a sendstrt. conn POINTER CAN BE NULL HERE ! ****************************************************************************/ void reply_sendstrt(connection_struct *conn, struct smb_request *req) { char *p; START_PROFILE(SMBsendstrt); if (! (*lp_msg_command())) { reply_doserror(req, ERRSRV, ERRmsgoff); END_PROFILE(SMBsendstrt); return; } memset(msgbuf,'\0',sizeof(msgbuf)); msgpos = 0; p = smb_buf(req->inbuf)+1; p += srvstr_pull_buf((char *)req->inbuf, req->flags2, msgfrom, p, sizeof(msgfrom), STR_ASCII|STR_TERMINATE) + 1; p += srvstr_pull_buf((char *)req->inbuf, req->flags2, msgto, p, sizeof(msgto), STR_ASCII|STR_TERMINATE) + 1; DEBUG( 3, ( "SMBsendstrt (from %s to %s)\n", msgfrom, msgto ) ); reply_outbuf(req, 0, 0); END_PROFILE(SMBsendstrt); return; } /**************************************************************************** Reply to a sendtxt. conn POINTER CAN BE NULL HERE ! ****************************************************************************/ void reply_sendtxt(connection_struct *conn, struct smb_request *req) { int len; char *msg; START_PROFILE(SMBsendtxt); if (! (*lp_msg_command())) { reply_doserror(req, ERRSRV, ERRmsgoff); END_PROFILE(SMBsendtxt); return; } msg = smb_buf(req->inbuf) + 1; len = SVAL(msg,0); len = MIN(len,sizeof(msgbuf)-msgpos); memcpy(&msgbuf[msgpos],msg+2,len); msgpos += len; DEBUG( 3, ( "SMBsendtxt\n" ) ); reply_outbuf(req, 0, 0); END_PROFILE(SMBsendtxt); return; } /**************************************************************************** Reply to a sendend. conn POINTER CAN BE NULL HERE ! ****************************************************************************/ void reply_sendend(connection_struct *conn, struct smb_request *req) { START_PROFILE(SMBsendend); if (! (*lp_msg_command())) { reply_doserror(req, ERRSRV, ERRmsgoff); END_PROFILE(SMBsendend); return; } DEBUG(3,("SMBsendend\n")); msg_deliver(); reply_outbuf(req, 0, 0); END_PROFILE(SMBsendend); return; }