/* @(#) $Id: mq_op.c,v 1.22 2007/03/24 01:20:12 dcid Exp $ */ /* Copyright (C) 2004-2006 Daniel B. Cid * All rights reserved. * * This program is a free software; you can redistribute it * and/or modify it under the terms of the GNU General Public * License (version 2) as published by the FSF - Free Software * Foundation */ #include "shared.h" #include "os_net/os_net.h" #ifndef WIN32 /* StartMQ v0.2, 2004/07/30 * Start the Message Queue. type: WRITE||READ */ int StartMQ(char * path, short int type) { if(type == READ) { return(OS_BindUnixDomain(path, 0660, OS_MAXSTR + 512)); } /* We give up to 21 seconds for the other end to * start */ else { int rc = 0; if(File_DateofChange(path) < 0) { sleep(1); if(File_DateofChange(path) < 0) { sleep(5); if(File_DateofChange(path) < 0) { merror(QUEUE_ERROR, __local_name, path, "Queue not found"); sleep(15); if(File_DateofChange(path) < 0) { return(-1); } } } } /* Wait up to 3 seconds to connect to the unix domain. * After three errors, exit. */ if((rc = OS_ConnectUnixDomain(path, OS_MAXSTR + 256)) < 0) { sleep(1); if((rc = OS_ConnectUnixDomain(path, OS_MAXSTR + 256)) < 0) { sleep(2); if((rc = OS_ConnectUnixDomain(path, OS_MAXSTR + 256)) < 0) { merror(QUEUE_ERROR, __local_name, path, strerror(errno)); return(-1); } } } debug1(MSG_SOCKET_SIZE, __local_name, OS_getsocketsize(rc)); return(rc); } } /* SendMSG v0.1, 2005/02/15 * Send a message to the queue. */ int SendMSG(int queue, char *message, char *locmsg, char loc) { int __mq_rcode; char tmpstr[OS_MAXSTR+1]; tmpstr[OS_MAXSTR] = '\0'; /* Checking for global locks */ os_wait(); if(loc == SECURE_MQ) { loc = message[0]; message++; if(message[0] != ':') { merror(FORMAT_ERROR, __local_name); return(0); } message++; /* Pointing now to the location */ snprintf(tmpstr,OS_MAXSTR,"%c:%s->%s",loc, locmsg, message); } else snprintf(tmpstr,OS_MAXSTR,"%c:%s:%s",loc,locmsg,message); /* queue not available */ if(queue < 0) return(-1); /* We attempt 5 times to send the message if * the receiver socket is busy. * After the first error, we wait 1 second. * After the second error, we wait more 3 seconds. * After the third error, we wait 5 seconds. * After the fourth error, we wait 10 seconds. * If we failed again, the message is not going * to be delivered and an error is sent back. */ if((__mq_rcode = OS_SendUnix(queue, tmpstr,0)) < 0) { /* Error on the socket */ if(__mq_rcode == OS_SOCKTERR) { merror("%s: socketerr (not available).", __local_name); close(queue); queue = -1; return(-1); } /* Unable to send. Socket busy */ sleep(1); if(OS_SendUnix(queue, tmpstr, 0) < 0) { /* When the socket is to busy, we may get some * error here. Just sleep 2 second and try * again. */ sleep(3); /* merror("%s: socket busy", __local_name); */ if(OS_SendUnix(queue, tmpstr,0) < 0) { sleep(5); merror("%s: socket busy ..", __local_name); if(OS_SendUnix(queue, tmpstr,0) < 0) { sleep(10); merror("%s: socket busy ..", __local_name); if(OS_SendUnix(queue, tmpstr,0) < 0) { /* Message is going to be lost * if the application does not care * about checking the error */ close(queue); queue = -1; return(-1); } } } } } return(0); } #endif /* EOF */