VR-Link API Documentation for HLA 1.3
vlCliServer.h
Go to the documentation of this file.
00001 /*********************************************************************
00002 ** Copyright (c) 1992-2010 VT MAK
00003 ** All rights reserved.
00004 *********************************************************************/
00009 #pragma once
00010 
00011 #include <stdio.h>
00012 #include <string.h>
00013 #include "vlUtil.h"
00014 
00015 #if DT_HAVE_DAEMON
00016 #include "vlShmQueue.h"
00017 
00018 #include "vlShmReader.h"
00019 #include "vlShmWriter.h"
00020 #endif
00021 
00022 #ifdef DtUSE_UTILITIES_NAMESPACE
00023 namespace DtUSE_UTILITIES_NAMESPACE
00024 {
00025 #endif
00026 
00027 /*****************************************
00028  * Constants used by Clients and Servers *
00029  *****************************************/
00030 
00031 #define DtCsClientPathSize 160
00032 #define DtCsMaxWarningSize 160
00033 
00034 #define DtCsVersionApril95  2
00035 #define DtCsVersionSeptember95  3
00036 #define DtCsVersionCurrent DtCsVersionSeptember95
00037 #define DtMinimumSendQSizeSupportedByVers2Server 32
00038 
00039 #define DtCsClientTypePacket   0
00040 #define DtCsClientTypeControl  1
00041 
00042 #define DtCsUseDefaultSize    -1
00043 
00044 #define DtCsFlagsRead                 0x0001
00045 #define DtCsFlagsWrite                0x0002
00046 #define DtCsFlagsReadWrite            (DtCsFlagsRead | DtCsFlagsWrite)
00047 
00048 #define DtCsFlagsServerChooseDropMode 0x0004
00049 #define DtCsFlagsServerDropOldest     0x0008
00050 #define DtCsFlagsClientDropOldest     0x0010
00051 #define DtCsFlagsDropOldest           (DtCsFlagsClientDropOldest | \
00052                                        DtCsFlagsServerDropOldest)
00053 
00054 #define DtCsFlagsReadResourceWait     0x0020
00055 #define DtCsFlagsWriteResourceWait    0x0040
00056 #define DtCsFlagsResourceWait         (DtCsFlagsReadResourceWait | \
00057                                        DtCsFlagsWriteResourceWait)
00058 
00059 #define DtCsFlagsDontNotify           0x0080
00060 #define DtCsFlagsControlOnly          0x0100
00061 
00062 
00063 /**********************************  
00064  * Messages from Client to Server *
00065  **********************************/
00066 
00067 
00069 
00070 #define DtCsMsgWaitingKind       0
00071 
00073 
00074 #define DtCsAddClientKind        1
00075 #define DtCsClientPacketKind     2
00076 #define DtCsControlReqKind       4
00077 #define DtCsFilterKind           5
00078 #define DtCsMulticastReqKind  13
00079 
00080     /**********************************  
00081      * Types of Control Req Messages  *
00082      **********************************/
00083 
00084 #define     DtCsCrExternal           0
00085 #define     DtCsCrInternal           1
00086 #define     DtCsCrTestClients        2
00087 #define     DtCsCrPing               3
00088 #define     DtCsCrState              4
00089 #define     DtCsCrCState             5
00090 #define     DtCsCrQuit               6
00091 #define     DtCsCrDisconnect         7
00092 #define     DtCsCrUnbundle           8
00093 #define     DtCsCrNoUnbundle         9
00094 
00095     /**********************************  
00096      *    Multicast Request Types     *
00097      **********************************/
00098 
00099 #define  DtCsMSubscribe    0
00100 #define  DtCsMUnsubscribe  1
00101 
00102 /**********************************  
00103  * Messages from Server to Client *
00104  **********************************/
00105 
00106 
00107 
00109 
00110 #define DtCsAckKind              6
00111 #define DtCsCliQuotaKind         7
00112 
00114 
00115 #define DtCsServerPacketKind     8
00116 #define DtCsStateReturnKind      9
00117 #define DtCsCStateReturnKind    10
00118 #define DtCsWarningKind         11
00119 #define DtCsNoticeKind          12
00120 
00121     /*****************************  
00122      * Types of Notice Messages  *
00123      *****************************/
00124 
00125 #define     DtCsNExternal           0
00126 #define     DtCsNInternal           1
00127 #define     DtCsNExtCliQuota        2
00128 #define     DtCsNPing               3
00129 #define     DtCsNClosing            4
00130 
00131 
00132 struct DtCsMsgHdr
00133 {
00134     DtU8 kind;
00135     DtU8 version;
00136 };
00137 
00138 /**************************************
00139  * Messages sent to Client and Server *
00140  **************************************/
00141 
00143 struct DtCsMsgWaiting
00144 {
00145     DtCsMsgHdr hdr;
00146 };
00147 
00148 /*******************************
00149  * Messages sent to the Server *
00150  *******************************/
00151 
00152 
00153 struct DtCsAddClient
00154 {
00155     DtCsMsgHdr hdr;
00156     DtU16      flags;
00157     DtInt32    server2ClientSize;
00158     DtInt32    client2ServerSize;
00159     DtInt32    clientProcessId;
00160     char       clientPath[DtCsClientPathSize];
00161 };
00162 
00165 
00166 struct DtCsClientPacket
00167 {
00168     DtCsMsgHdr hdr;
00169     DtU16      padding;
00170     DtU32      length;
00171 };
00172 
00173 struct DtCsControlReq
00174 {
00175     DtCsMsgHdr hdr;
00176     DtU16      request;
00177     DtU32 clientId;
00178 };
00179 
00180 struct DtCsMulticastReq
00181 {
00182     DtCsMsgHdr    hdr;
00183     DtU16         request;
00184     DtU32   addr;
00185     DtU32   clientId;
00186 };
00187 
00188 #define DtCsFilterTypeExercise  0
00189 #define DtCsFilterTypeVersion   1
00190 #define DtCsFilterTypePduKind   2
00191 #define DtCsFilterTypeIpAddr    3
00192 
00193 #define DtCsFilterOpSetOperator 0
00194 #define DtCsFilterOpAddValue    1
00195 
00196 #define DtCsOperatorEQ          0
00197 #define DtCsOperatorNEQ         1
00198 
00199 struct DtCsFilter
00200 {
00201     DtCsMsgHdr hdr;
00202     DtU8       filterType;
00203     DtU8       filterOp;
00204     DtU32      value;
00205     DtU32      clientId;
00206 };
00207 
00208 
00209 /*******************************
00210  * Messages sent to the Server *
00211  *******************************/
00212 
00213 struct DtCsAck
00214 {
00215     DtCsMsgHdr hdr;
00216     DtU8       internal;
00217     DtU8       padding;      
00218     DtU32      clientId;
00219     DtU32      shmKey;
00220     DtU32      semKey;
00221     DtInt32    server2ClientSize;
00222     DtInt32    client2ServerSize;
00223 };
00224 
00226 struct DtCsCliQuota
00227 {
00228     DtCsMsgHdr hdr;
00229 };
00230 
00232 DT_DLL_VLUTIL struct DtCsServerMsgWaiting
00233 {
00234     DtCsMsgHdr hdr;
00235 };
00236 
00239 
00240 struct DtCsServerPacket
00241 {
00242         DtCsMsgHdr hdr;
00243    DtU16      padding1;
00244    DtU32      sourceAddr;
00245    DtU32      arrivalTime;
00246    DtU32      length;
00247 };
00248 
00249 struct DtCsStateReturn
00250 {
00251     DtCsMsgHdr hdr;
00252     DtU8       internal;
00253     DtU8       unbundling;
00254     DtU16      numPacketClients;
00255     DtU16      numControlClients;
00256     DtInt32    clientQuota;  
00257     DtU32      port;
00258 };
00259 
00261 
00262 #define DtCsCStateServerBlockRead  0x01
00263 #define DtCsCStateServerBlockWrite 0x02
00264 #define DtCsCStateClientBlockRead  0x04
00265 #define DtCsCStateClientBlockWrite 0x08
00266 
00267 struct DtCsCStateReturn
00268 {
00269     DtCsMsgHdr hdr;
00270     DtU16      flags;
00271     DtU8       serverDropOldest;
00272     DtU8       serverResourceWait;
00273     DtU8       blockFlags;
00274     DtU8       padding;
00275 
00276     DtInt32    processId;
00277     DtU32      clientId;
00278     
00279     DtInt32    client2ServerSize;
00280     DtInt32    server2ClientSize;
00281 
00282     DtInt32    packetsRcvdFromClient;
00283     DtInt32    packetsSentToClient;
00284 
00285     DtInt32    newPacketsDropped;
00286     DtInt32    oldPacketsDropped;
00287 };
00288 
00289 struct DtCsWarning
00290 {
00291     DtCsMsgHdr hdr;
00292     DtU16      reason;  
00293     char       warningMsg[DtCsMaxWarningSize];
00294 };
00295 
00296 struct DtCsNotice
00297 {
00298     DtCsMsgHdr hdr;
00299     DtU16      notice;
00300 };
00301 
00302 
00303 union DtCsMsg
00304 {
00306     DtCsMsgHdr              hdr;
00307 
00308     DtCsMsgWaiting          msgWaiting;
00309 
00310     DtCsAddClient           addClient;
00311     DtCsClientPacket        clientPacket;
00312     DtCsControlReq          controlReq;
00313     DtCsMulticastReq     multicastReq;
00314     DtCsFilter              filter;
00315 
00316     DtCsAck                 ack;
00317     DtCsCliQuota            cliQuota;
00318     DtCsServerPacket        serverPacket;
00319     DtCsStateReturn         stateReturn;
00320     DtCsCStateReturn        cStateReturn;
00321     DtCsWarning             warning;
00322     DtCsNotice              notice;
00323 };
00324 
00325 
00326 /*
00327  *
00328  */
00329 
00330 class DT_DLL_VLUTIL DtClientServerMsg
00331 {
00332   public:
00333     DtClientServerMsg() {}
00334     DtClientServerMsg(DtCsMsg *msg);
00335 
00336     virtual ~DtClientServerMsg() {}
00337 
00338     virtual int send() = 0;
00339     virtual void print();
00340 
00341     DtU8 kind()      { return msg.hdr.kind; }
00342     DtU8 version()   { return msg.hdr.version; }
00343     size_t msgSize() { return size; }
00344 
00345   protected:
00346     DtCsMsg msg;
00347     size_t size;
00348 
00349 };
00350 
00351 class DT_DLL_VLUTIL DtSocketMsg : public DtClientServerMsg
00352 {
00353   public:
00354     DtSocketMsg(int sockId) { sendFd = sockId; }
00355 
00356     DtSocketMsg(int sockId, DtCsMsg *m) : DtClientServerMsg(m) 
00357    { sendFd = sockId; }
00358 
00359     virtual ~DtSocketMsg() {}
00360 
00361     virtual int send();
00362 
00363   private:
00364     int sendFd;
00365 };
00366 
00367 #if DT_HAVE_DAEMON
00368 class DT_DLL_VLUTIL DtShmMsg : public DtClientServerMsg
00369 {
00370   public:
00371     DtShmMsg(DtShmMsgQueueWriter *w) { writer = w; }
00372     DtShmMsg(DtShmMsgQueueWriter *w, DtCsMsg *m) : DtClientServerMsg(m) 
00373    { writer = w; }
00374 
00375     virtual ~DtShmMsg() {}
00376 
00377     virtual int send();
00378 
00379   protected:
00380     DtShmMsgQueueWriter *writer;
00381 };
00382 #endif
00383 
00384 class DT_DLL_VLUTIL DtCsMsgWaitingMsg : public DtSocketMsg
00385 {
00386   public:
00387 
00388     DtCsMsgWaitingMsg(int fd, DtCsMsg *m) : DtSocketMsg(fd, m) {}
00389 
00390     DtCsMsgWaitingMsg(int fd);
00391 
00392     virtual ~DtCsMsgWaitingMsg() {}
00393 };
00394 
00395 
00396 class DT_DLL_VLUTIL DtCsAddClientMsg : public DtSocketMsg
00397 {
00398   public:
00399 
00400     DtCsAddClientMsg(int fd, DtCsMsg *m) : DtSocketMsg(fd, m) {}
00401 
00402     DtCsAddClientMsg(int fd, DtU16 flgs, DtInt32 s2cSize, DtInt32 c2sSize, 
00403    DtInt32 pid, char *path);
00404 
00405     virtual ~DtCsAddClientMsg() {}
00406     
00407     DtU16 flags()               { return msg.addClient.flags; }
00408 
00409     void setServer2ClientSize(DtU32 s){ msg.addClient.server2ClientSize = s; }
00410     DtInt32 server2ClientSize() { return msg.addClient.server2ClientSize; }
00411 
00412     void setClient2ServerSize(DtU32 s){ msg.addClient.client2ServerSize = s; }
00413     DtInt32 client2ServerSize() { return msg.addClient.client2ServerSize; }
00414 
00415     DtInt32 clientProcessId()   { return msg.addClient.clientProcessId; }
00416     char *clientPath()          { return msg.addClient.clientPath; }
00417 };
00418 
00419 #if DT_HAVE_DAEMON
00420 class DT_DLL_VLUTIL DtCsClientPacketMsg : public DtShmMsg
00421 {
00422   public:
00423 
00424     DtCsClientPacketMsg(DtShmMsgQueueWriter * w, DtCsMsg *m, char *d)
00425         : DtShmMsg(w, m) { theBytes = d; }
00426 
00427     DtCsClientPacketMsg(DtShmMsgQueueWriter * w, DtU32 length, char *d);
00428 
00429     virtual ~DtCsClientPacketMsg() {}
00430 
00431     int send();
00432 
00433     void setData(char *d) { theBytes = d; };
00434     char *data() { return theBytes; }
00435 
00436     DtU32 length() { return msg.clientPacket.length; }
00437     void setLength(DtU32 s) { msg.clientPacket.length = s; };
00438 
00439   private:
00440     char *theBytes;
00441 };
00442 
00443 class DT_DLL_VLUTIL DtCsControlReqMsg : public DtSocketMsg
00444 {
00445   public:
00446 
00447     DtCsControlReqMsg(int fd, DtCsMsg *m) : DtSocketMsg(fd, m) {}
00448     DtCsControlReqMsg(int fd, DtU16 request, DtU32 clientId);
00449 
00450     virtual ~DtCsControlReqMsg() {}
00451 
00452     void setRequest(DtU16 r) {  msg.controlReq.request = r; }
00453     DtU16 request()    { return msg.controlReq.request; }
00454     DtU32 clientId()   { return msg.controlReq.clientId; }
00455     void setClientId(DtU32 id) {msg.controlReq.clientId = id; }
00456 };
00457 
00458 class DT_DLL_VLUTIL DtCsMulticastReqMsg : public DtSocketMsg
00459 {
00460   public:
00461 
00462     DtCsMulticastReqMsg(int fd, DtCsMsg *m) : DtSocketMsg(fd, m) {}
00463     DtCsMulticastReqMsg(int fd, DtU16 request, DtIpv4Addr addr, 
00464          DtU32 clientId);
00465 
00466     virtual ~DtCsMulticastReqMsg() {}
00467 
00468     void setRequest(DtU16 r) {  msg.multicastReq.request = r; }
00469     DtU16 request()    { return msg.multicastReq.request; }
00470     DtU32 clientId()   { return msg.multicastReq.clientId; }
00471     void setClientId(DtU32 id) {msg.multicastReq.clientId = id; }
00472     void setAddr(DtIpv4Addr addr) {msg.multicastReq.addr = (DtU32) addr; }
00473     DtIpv4Addr addr() { return (DtIpv4Addr) msg.multicastReq.addr; }
00474 };
00475 
00476 class DT_DLL_VLUTIL DtCsFilterMsg : public DtSocketMsg
00477 {
00478   public:
00479     
00480     DtCsFilterMsg(int fd, DtCsMsg *m) : DtSocketMsg(fd, m) {}
00481     DtCsFilterMsg(int fd, DtU8 type, DtU8 op, DtU32 val, DtU32 clientId);
00482 
00483     virtual ~DtCsFilterMsg() {}
00484 
00485     DtU8 filterType()          { return msg.filter.filterType; }
00486 
00487     DtU8 filterOp()            { return msg.filter.filterOp; }
00488     void setFilterOp (DtU8 op) { msg.filter.filterOp = op; }
00489 
00490     DtU32 value()              { return msg.filter.value; }
00491     void setValue (DtU32 val)  { msg.filter.value = val; }
00492     DtU32 clientId() {return msg.filter.clientId; }
00493     void setClientId(DtU32 id) {msg.filter.clientId = id; }
00494 };
00495 
00496 
00497 class DT_DLL_VLUTIL DtCsAckMsg : public DtSocketMsg
00498 {
00499   public:
00500 
00501     DtCsAckMsg(int fd, DtCsMsg *m) : DtSocketMsg(fd, m) {}
00502 
00503     DtCsAckMsg(int fd, DtU8 internal, DtU32 clientId, DtU32 shmKey,
00504       DtU32 semKey, DtInt32 server2ClientSize, DtInt32 client2ServerSize);
00505 
00506     virtual ~DtCsAckMsg() {}
00507 
00508     DtU8 internal()             { return msg.ack.internal; }
00509     DtU32 clientId()            { return msg.ack.clientId; }
00510     DtU32 shmKey()              { return msg.ack.shmKey; }
00511     DtU32 semKey()              { return msg.ack.semKey; }
00512     DtInt32 server2ClientSize() { return msg.ack.server2ClientSize; }
00513     DtInt32 client2ServerSize() { return msg.ack.client2ServerSize; }
00514 
00515 };
00516 
00517 class DT_DLL_VLUTIL DtCsCliQuotaMsg : public DtSocketMsg
00518 {
00519   public:
00520 
00521     DtCsCliQuotaMsg(int fd, DtCsMsg *m) : DtSocketMsg(fd, m) {}
00522 
00523     DtCsCliQuotaMsg(int fd);
00524 
00525     virtual ~DtCsCliQuotaMsg() {}
00526 };
00527 
00528 class DT_DLL_VLUTIL DtCsServerPacketMsg : public DtShmMsg
00529 {
00530   public:
00531 
00532     DtCsServerPacketMsg(DtShmMsgQueueWriter * w, DtCsMsg *m, char *d) 
00533    : DtShmMsg(w, m) { theBytes = d; }
00534 
00535     DtCsServerPacketMsg(DtShmMsgQueueWriter * w, DtU32 sourceAddr, DtU32 
00536    arrivalTime, DtU32 length, char *d);
00537 
00538     virtual ~DtCsServerPacketMsg() {}
00539 
00540     int send();
00541 
00542     void setData(char *d)        { theBytes = d; };
00543     char *data()                 { return theBytes; }
00544 
00545     void setLength(DtU32 s)      { msg.serverPacket.length = s; };
00546     DtU32 length()               { return msg.serverPacket.length; }
00547 
00548     void setSourceAddr(DtU32 s)  { msg.serverPacket.sourceAddr = s; }
00549     DtU32 sourceAddr()           { return msg.serverPacket.sourceAddr; }
00550 
00551     void setArrivalTime(DtU32 a) { msg.serverPacket.arrivalTime = a; }
00552     DtU32 arrivalTime()          { return msg.serverPacket.arrivalTime; }
00553 
00554   private:
00555 
00556     char *theBytes;
00557 };
00558 
00559 class DT_DLL_VLUTIL DtCsStateReturnMsg : public DtShmMsg
00560 {
00561   public:
00562 
00563     DtCsStateReturnMsg(DtShmMsgQueueWriter * w, DtCsMsg *m) : DtShmMsg(w, m) {}
00564 
00565     DtCsStateReturnMsg(DtShmMsgQueueWriter * w, DtU8 internal, DtU16 
00566    numPacketClients, DtU16 numControlClients, DtInt32 clientQuota,
00567    DtU32 prt, DtU8 ub);
00568 
00569     virtual ~DtCsStateReturnMsg() {}
00570     
00571     void print();
00572 
00573     DtU8 internal()           { return msg.stateReturn.internal; }
00574     DtU8 unbundling()         { return msg.stateReturn.unbundling; }
00575     DtU16 numPacketClients()  { return msg.stateReturn.numPacketClients; }
00576     DtU16 numControlClients() { return msg.stateReturn.numControlClients; }
00577     DtInt32 clientQuota()     { return msg.stateReturn.clientQuota; }
00578     DtU32  port()             { return msg.stateReturn.port; }
00579 };
00580 
00581 class DT_DLL_VLUTIL DtCsCStateReturnMsg : public DtShmMsg
00582 {
00583   public:
00584 
00585     DtCsCStateReturnMsg(DtShmMsgQueueWriter * w, DtCsMsg *m) : DtShmMsg(w, m) {}
00586 
00587     DtCsCStateReturnMsg(DtShmMsgQueueWriter * w, DtU16 flags, 
00588    DtU8 serverDropOldest, DtU8 serverResourceWait, DtU8 blockFlags,
00589    DtInt32 processId, DtU32 clientId, DtInt32 client2ServerSize, 
00590    DtInt32 server2ClientSize, DtInt32 packetsRcvdFromClient, 
00591    DtInt32 packetsSendToClient, DtInt32 newPacketsDropped, 
00592    DtInt32 oldPacketsDropped);
00593     
00594     virtual ~DtCsCStateReturnMsg() {}
00595 
00596     void print();
00597 
00598     DtU16 flags()                   {return msg.cStateReturn.flags; }
00599     DtU8 serverDropOldest()         {return msg.cStateReturn.serverDropOldest; }
00600     DtU8 serverResourceWait()       {return 
00601                    msg.cStateReturn.serverResourceWait; }
00602     DtU8 blockFlags()               {return msg.cStateReturn.blockFlags; }
00603 
00604     DtInt32 processId()             {return msg.cStateReturn.processId; }
00605     DtU32 clientId()                {return msg.cStateReturn.clientId; }
00606     DtInt32 client2ServerSize()     {return msg.cStateReturn.client2ServerSize;}
00607     DtInt32 server2ClientSize()     {return msg.cStateReturn.server2ClientSize;}
00608     DtInt32 packetsRcvdFromClient() {return 
00609                    msg.cStateReturn.packetsRcvdFromClient; }
00610     DtInt32 packetsSendToClient()   {return 
00611                    msg.cStateReturn.packetsSentToClient; }
00612     DtInt32 newPacketsDropped()     {return 
00613                    msg.cStateReturn.newPacketsDropped; }
00614     DtInt32 oldPacketsDropped()     {return 
00615                    msg.cStateReturn.oldPacketsDropped; }
00616 };
00617 
00618 class DT_DLL_VLUTIL DtCsWarningMsg : public DtShmMsg
00619 {
00620   public:
00621 
00622     DtCsWarningMsg(DtShmMsgQueueWriter * w, DtCsMsg *m) : DtShmMsg(w, m) {}
00623 
00624     DtCsWarningMsg(DtShmMsgQueueWriter * w, DtU16 reason, char *warningMsg);
00625 
00626     virtual ~DtCsWarningMsg() {}
00627 
00628     void print();
00629 
00630     DtU16 reason()      { return msg.warning.reason; }
00631     void setReason (DtU16 r) { msg.warning.reason = r; }
00632     char *warningMsg()  { return msg.warning.warningMsg; };
00633     void setWarningMsg (char *m) 
00634    { strncpy(msg.warning.warningMsg, m, sizeof(msg.warning.warningMsg)); }
00635 };
00636 
00637 class DT_DLL_VLUTIL DtCsNoticeMsg : public DtShmMsg
00638 {
00639   public:
00640 
00641     DtCsNoticeMsg(DtShmMsgQueueWriter * w, DtCsMsg *m) : DtShmMsg(w, m) {}
00642 
00643     DtCsNoticeMsg(DtShmMsgQueueWriter * w, DtU16 notice);
00644 
00645     void print();
00646 
00647     virtual ~DtCsNoticeMsg() {}
00648 
00649     int notice()                { return msg.notice.notice; }
00650     void setNotice(DtU16 n) { msg.notice.notice = n; }
00651 };
00652 #endif
00653 
00654 /* ---------------------- SUPPORT UTILS ---------------------- */
00655 
00656 #if DT_HAVE_DAEMON
00657 void DtPacketServerRequestPath(unsigned n, char* requestPath, int vers=DtCsVersionCurrent);
00658 
00659 #endif //! !PCFTP
00660 
00661 /* if who is NULL, warning msgs will not be printed */
00662 enum DtOpenUnixDgramAction { DtBIND, DtCONNECT };
00663 int DtOpenUnixDgram(char *path, DtOpenUnixDgramAction action, char *who);
00664 int DtPacketServerIsAlive(int port);
00665 
00666 #ifdef DtUSE_UTILITIES_NAMESPACE
00667 } 
00668 #endif
00669 
00670 

Document ID: Generated on Mon May 14 08:06:18 EDT 2012 from SVN revision 114750
Copyright © 2005-2012 VT MÄK Inc. All Rights Reserved (www.mak.com)