00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "defs.h"
00022 #include "smi_msg.h"
00023 #ifdef HAVE_SYSVMSG
00024 #include <sys/msg.h>
00025
00026 typedef struct {
00027 SMIENTITY sq_entity;
00028 int sq_qid_server;
00029 int sq_qid_client;
00030 char sq_name[SERVER_NAME_MAX];
00031 struct client_id sq_client;
00032 size_t sq_msgsize;
00033 struct smi_msg *sq_msg;
00034 } SMIQ_MSG;
00035
00036 static void mkmsg_name_server(const SMIQ_MSG *p, char *msgname,
00037 size_t msgname_max)
00038 {
00039 snprintf(msgname, msgname_max, "/tmp/smimsg-%s", p->sq_name);
00040 }
00041
00042 SMIQ *smi_open_msg(const char *name, SMIENTITY entity, size_t msgsize)
00043 {
00044 SMIQ_MSG *p = NULL;
00045 char msgname[SERVER_NAME_MAX + 100];
00046 key_t key;
00047
00048 ec_null( p = calloc(1, sizeof(SMIQ_MSG)) )
00049 p->sq_msgsize = msgsize + offsetof(struct smi_msg, smi_data);
00050 ec_null( p->sq_msg = calloc(1, p->sq_msgsize) )
00051 p->sq_qid_server = p->sq_qid_client = -1;
00052 p->sq_entity = entity;
00053 if (strlen(name) >= SERVER_NAME_MAX) {
00054 errno = ENAMETOOLONG;
00055 EC_FAIL
00056 }
00057 strcpy(p->sq_name, name);
00058 mkmsg_name_server(p, msgname, sizeof(msgname));
00059 (void)close(open(msgname, O_WRONLY | O_CREAT, 0));
00060 ec_neg1( key = ftok(msgname, 1) )
00061 if (p->sq_entity == SMI_SERVER) {
00062 if ((p->sq_qid_server = msgget(key, PERM_FILE)) != -1)
00063 (void)msgctl(p->sq_qid_server, IPC_RMID, NULL);
00064 ec_neg1( p->sq_qid_server = msgget(key, IPC_CREAT | PERM_FILE) )
00065 }
00066 else {
00067 ec_neg1( p->sq_qid_server = msgget(key, 0) )
00068 ec_neg1( p->sq_qid_client = msgget(IPC_PRIVATE, PERM_FILE) );
00069 }
00070 return (SMIQ *)p;
00071
00072 EC_CLEANUP_BGN
00073 if (p != NULL)
00074 (void)smi_close_msg((SMIQ *)p);
00075 return NULL;
00076 EC_CLEANUP_END
00077 }
00078
00079 bool smi_close_msg(SMIQ *sqp)
00080 {
00081 SMIQ_MSG *p = (SMIQ_MSG *)sqp;
00082
00083 if (p->sq_entity == SMI_SERVER) {
00084 char msgname[FILENAME_MAX];
00085
00086 (void)msgctl(p->sq_qid_server, IPC_RMID, NULL);
00087 mkmsg_name_server(p, msgname, sizeof(msgname));
00088 (void)unlink(msgname);
00089 }
00090 else
00091 (void)msgctl(p->sq_qid_client, IPC_RMID, NULL);
00092 free(p->sq_msg);
00093 free(p);
00094 return true;
00095 }
00096
00097 bool smi_send_getaddr_msg(SMIQ *sqp, struct client_id *client,
00098 void **addr)
00099 {
00100 SMIQ_MSG *p = (SMIQ_MSG *)sqp;
00101
00102 if (p->sq_entity == SMI_SERVER)
00103 p->sq_client = *client;
00104 *addr = p->sq_msg;
00105 return true;
00106 }
00107
00108 bool smi_send_release_msg(SMIQ *sqp)
00109 {
00110 SMIQ_MSG *p = (SMIQ_MSG *)sqp;
00111 int qid_receiver;
00112
00113 p->sq_msg->smi_mtype = 1;
00114 if (p->sq_entity == SMI_SERVER)
00115 qid_receiver = p->sq_client.c_id1;
00116 else {
00117 qid_receiver = p->sq_qid_server;
00118 p->sq_msg->smi_client.c_id1 = p->sq_qid_client;
00119 }
00120 ec_neg1( msgsnd(qid_receiver, p->sq_msg,
00121 p->sq_msgsize - sizeof(p->sq_msg->smi_mtype), 0) )
00122 return true;
00123
00124 EC_CLEANUP_BGN
00125 return false;
00126 EC_CLEANUP_END
00127 }
00128
00129 bool smi_receive_getaddr_msg(SMIQ *sqp, void **addr)
00130 {
00131 SMIQ_MSG *p = (SMIQ_MSG *)sqp;
00132 int qid_receiver;
00133 ssize_t nrcv;
00134
00135 if (p->sq_entity == SMI_SERVER)
00136 qid_receiver = p->sq_qid_server;
00137 else
00138 qid_receiver = p->sq_qid_client;
00139 ec_neg1( nrcv = msgrcv(qid_receiver, p->sq_msg,
00140 p->sq_msgsize - sizeof(p->sq_msg->smi_mtype), 0, 0) )
00141 *addr = p->sq_msg;
00142 return true;
00143
00144 EC_CLEANUP_BGN
00145 return false;
00146 EC_CLEANUP_END
00147 }
00148
00149 bool smi_receive_release_msg(SMIQ *sqp)
00150 {
00151 return true;
00152 }
00153
00154
00155 #else
00156 SMIQ *smi_open_msg(const char *name, SMIENTITY entity, size_t msgsize)
00157 {
00158 errno = ENOSYS;
00159 return NULL;
00160 }
00161
00162 bool smi_close_msg(SMIQ *sqp)
00163 {
00164 errno = ENOSYS;
00165 return false;
00166 }
00167
00168 bool smi_send_getaddr_msg(SMIQ *sqp, struct client_id *client,
00169 void **addr)
00170 {
00171 errno = ENOSYS;
00172 return false;
00173 }
00174
00175 bool smi_send_release_msg(SMIQ *sqp)
00176 {
00177 errno = ENOSYS;
00178 return false;
00179 }
00180
00181 bool smi_receive_getaddr_msg(SMIQ *sqp, void **addr)
00182 {
00183 errno = ENOSYS;
00184 return false;
00185 }
00186
00187 bool smi_receive_release_msg(SMIQ *sqp)
00188 {
00189 errno = ENOSYS;
00190 return false;
00191 }
00192
00193 #endif