program msgtool;

Uses ipc,baseunix,errors;

const
	MAX_SEND_SIZE = 80; //Hasta 254 para poder poner un #0 y probar con C

Type
  PMyMsgBuf = ^TMyMsgBuf;
  TMyMsgBuf = record
    mtype : clong;
    mtext : string[MAX_SEND_SIZE + 1];
  end;

Procedure DoError (Const Msg : string);
var
	error: Integer;
begin
	error:= fpgeterrno;
  Writeln (msg,' returned an error : ', error, ', ', strerror(error));
  halt(1);
end;

Procedure SendMessage (Id : Longint;
                       Var Buf : TMyMsgBuf;
                       MType : Longint;
                       Const MText : ShortString);

begin
  Writeln ('Sending message. Type= ', MType, ', Text= ', MText, ', Length(MText)= ', Length(MText));
  Buf.mtype:= mtype;
  Buf.Mtext:= mtext + #0;
  If  msgsnd(Id, PMsgBuf(@Buf), length(mtext) + 1, 0)=-1 then
    DoError('msgsnd');
end;

Procedure ReadMessage (ID : Longint;
                       Var Buf : TMyMsgBuf;
                       MType : clong);
var
  res: cint;
begin
  Writeln ('Reading message. Type= ', MType, ', MAX_SEND_SIZE= ', MAX_SEND_SIZE);
  Buf.MType:= MType;
  res:= msgrcv(ID,PMSGBuf(@Buf), MAX_SEND_SIZE, mtype, IPC_NOWAIT or MSG_NOERROR);
  writeln( 'RES: ', res );
  if res > 0 then
  begin
    setlength( buf.mtext, res );
    Writeln ('Type : ',buf.mtype,' Text : ',buf.mtext);
  end
  else
    DoError ('msgrcv');
end;

Procedure RemoveQueue ( ID : Longint);

begin
  If msgctl (id,IPC_RMID,Nil)<>-1 then
    Writeln ('Removed Queue with id ',Id);
end;

Procedure ChangeQueueMode (ID,mode : longint);

Var QueueDS : TMSQid_ds;

begin
  If  msgctl (Id,IPC_STAT,@QueueDS)=-1 then
    DoError ('msgctl : stat');
  Writeln ('Old permissions : ',QueueDS.msg_perm.mode);
  QueueDS.msg_perm.mode:=Mode;
  if msgctl (ID,IPC_SET,@QueueDS)=0 then
    Writeln ('New permissions : ',QueueDS.msg_perm.mode)
  else
   DoError ('msgctl : IPC_SET');
end;

procedure usage;

begin
  Writeln ('Usage : msgtool s(end)    <type> <text> (max ', MAX_SEND_SIZE, ' characters)');
  Writeln ('                r(eceive) <type>');
  Writeln ('                d(elete)');
  Writeln ('                m(ode) <decimal mode>');
  halt(1);
end;

Function StrToInt (S : String): longint;

Var M : longint;
    C : Integer;

begin
  val (S,M,C);
  If C<>0 Then DoError ('StrToInt : '+S);
  StrToInt:=M;
end;

Var
  Key : TKey;
  ID  : longint;
  Buf : TMyMsgBuf;

const ipckey = '/home/palfaro/nettopos/archikeys/keyColaMensajes'#0;

begin
//	writeln('sizeof(pointer)= ', sizeof(pointer));
//	writeln('sizeof(size_t)= ', sizeof(size_t));
//	writeln('sizeof(cint)= ', sizeof(cint));
//	writeln('sizeof(clong)= ', sizeof(clong));

 If Paramcount<1 then Usage;
  key :=Ftok(@ipckey[1], 1);
  ID:=msgget(key,IPC_CREAT or 438);
  writeln('Obtuve la cola de mensajes con id=', ID, ', ipckey= ', ipckey);
  If ID<0 then DoError ('MsgGet');
  Case upCase(Paramstr(1)[1]) of
   'S' : If ParamCount<>3 then
           Usage
         else
           SendMessage (id,Buf,StrToInt(Paramstr(2)),paramstr(3));
   'R' : If ParamCount<>2 then
           Usage
         else
           ReadMessage (id,buf,strtoint(Paramstr(2)));
   'D' : If ParamCount<>1 then
           Usage
         else
           RemoveQueue (ID);
   'M' : If ParamCount<>2 then
           Usage
         else
           ChangeQueueMode (id,strtoint(paramstr(2)));
   else
     Usage
   end;
end.
