(* Программа etest -- ввод имен объектов в очередь. *)
{$mode objfpc}
uses ipc,linux,stdio,sysutils;
{$i q.inc}

procedure warn (s:pchar);
begin
  writeln(stderr, 'Предупреждение: ', s);
end;

(* Инициализация очереди -- получить идентификатор очереди *)
function init_queue:longint;
var
  queue_id:longint;
begin
  (* Попытка создания или открытия очереди сообщений *)
  queue_id := msgget (QKEY, IPC_CREAT or QPERM);
  if queue_id = -1 then
    perror ('Ошибка вызова msgget');
  init_queue:=queue_id;
end;


(* Процедура enter -- поместить объект в очередь *)
function enter (objname:string;priority:longint):boolean;
var
  len, s_qid:longint;
  s_entry:q_entry;	(* структура для хранения сообщений *)
begin
  (* Проверка длины имени и уровня приоритета *)
  len := length (objname);
  if len > MAXOBN then
  begin
    warn ('слишком длинное имя');
    enter:=false;
    exit;
  end;
  if (priority > MAXPRIOR) or (priority < 0) then
  begin
    warn ('недопустимый уровень приоритета');
    enter:=false;
    exit;
  end;

  (* Инициализация очереди сообщений, если это необходимо *)
  s_qid := init_queue;
  if s_qid = -1 then
  begin
    enter:=false;
    exit;
  end;
  (* Инициализация структуры переменной s_entry *)
  s_entry.mtype := priority;
  strlcopy (s_entry.mtext, @objname[1], MAXOBN);
  (* Посылаем сообщение, выполнив ожидание, если это необходимо *)
  if not msgsnd (s_qid, @s_entry, len, 0) then
  begin
    perror ('Ошибка вызова msgsnd');
    enter:=false;
    exit;
  end
  else
    enter:=true;
end;


var
  priority:longint;
begin
  if paramcount <> 2 then
  begin
    writeln(stderr, 'Применение: ',paramstr(0),' имя приоритет');
    halt (1);
  end;
  try
    priority:=strtoint(paramstr(2));
  except
    on e:econverterror do
    begin
      warn ('Нечисловой приоритет');
      halt (2);
    end;
  end;
  if (priority <= 0) or (priority > MAXPRIOR) then
  begin
    warn ('Недопустимый приоритет');
    halt (2);
  end;
  if not enter (paramstr(1), priority) then
  begin
    warn ('Ошибка в процедуре enter');
    halt (3);
  end;
  halt (0);
end.
