home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / PASCAL / ECO30603.ZIP / ECO30603.LZH / ECOLIBII / ECO_NOVL.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1992-12-11  |  53.8 KB  |  2,122 lines

  1. unit eco_novl;
  2.  
  3. interface
  4. uses
  5.   dos
  6.   
  7.   ;
  8.  
  9.  
  10.  
  11. type
  12.   integer = word;
  13.  
  14.  
  15. const
  16.   months : array [1..12] of string[3] = (
  17.     'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 
  18.     'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
  19.   );
  20.   hexdigits : array[0..15] of char = '0123456789ABCDEF';
  21.  
  22.  
  23. var
  24.   { as programmer first call getserverinfo. }
  25.   serverinfo : record
  26.     returnlength                  :              integer;
  27.     server                        : array[1..48] of byte;
  28.     netwarevers                   :                 byte;
  29.     netwaresubv                   :                 byte;
  30.     connectionmax                 :  array[1..2] of byte;
  31.     connectionuse                 :  array[1..2] of byte;
  32.     maxconvol                     :  array[1..2] of byte;
  33.     os_revision                   :                 byte;
  34.     sft_level                     :                 byte;
  35.     tts_level                     :                 byte;
  36.     peak_used                     :  array[1..2] of byte;
  37.     accounting_version            :                 byte;
  38.     vap_version                   :                 byte;
  39.     queuing_version               :                 byte;
  40.     print_server_version          :                 byte;
  41.     virtual_console_version       :                 byte;
  42.     security_restrictions_version :                 byte;
  43.     internetwork_version_version  :                 byte;
  44.     undefined                     : array[1..60] of byte;
  45.     peak_connections_used         :              integer;
  46.     connections_max               :              integer;
  47.     connections_in_use            :              integer;
  48.     max_connected_volumes         :              integer;
  49.     name                          :               string;
  50.   end;
  51.  
  52.  
  53.  
  54.   procedure getconnectioninfo(
  55.     var logicalstationno : integer;
  56.     var name, hex_id      :  string;
  57.     var conntype         : integer;
  58.     var datetime         :  string;
  59.     var error            : integer
  60.   );
  61.   { returns username and login date/time when you supply the station number. }
  62.  
  63.   procedure clear_connection(
  64.     connection_number : integer; var error : integer
  65.   );
  66.   { kicks the workstation off the server}
  67.  
  68.   procedure gethexid(var userid, hexid: string; var error: integer);
  69.   { returns the novell hexid of an username when you supply the username. }
  70.  
  71.   procedure getserverinfo;
  72.   { returns various info of the default server }
  73.  
  74.   procedure getuser(
  75.     var _station: integer; var _username: string; var error:integer
  76.   );
  77.   { returns logged-in station username when you supply the station number. }
  78.  
  79.   procedure getnode(var hex_addr: string; var error: integer);
  80.   { returns your physical network node in hex. }
  81.  
  82.   procedure getstation(var _station: integer; var error: integer);
  83.   { returns the station number of your workstation }
  84.  
  85.   procedure getservername(var servername : string; var error : integer);
  86.   { returns the name of the current server }
  87.  
  88.   procedure send_message_to_username(
  89.     username, message: string; var error: integer
  90.   );
  91.   { sends a novell message to the userid's workstation }
  92.  
  93.   procedure send_message_to_station(
  94.     station: integer; message: string; var error: integer
  95.   );
  96.   { sends a message to the workstation station # }
  97.  
  98.   procedure get_volume_name(
  99.     var volume_name: string; volume_number: integer; var error: integer
  100.   );
  101.   { gets the volume name from novell network drive }
  102.   { example:  sys    note: default drive must be a }
  103.   { network drive.                                 }
  104.  
  105.   procedure get_realname(
  106.     var userid: string; var realname: string; var error: integer
  107.   );
  108.   { you supply the userid, and it returns the realname as stored by syscon. }
  109.   { example:  userid=mbramwel   realname=mark bramwell }
  110.  
  111.   procedure get_broadcast_mode(var bmode: integer);
  112.   procedure set_broadcast_mode(bmode: integer);
  113.   procedure get_broadcast_message(var bmessage: string; var error: integer);
  114.  
  115.   procedure get_server_datetime(
  116.     var _year, _month, _day, _hour, _min, _sec, _dow: integer
  117.   );
  118.   { pulls from the server the date, time and day of week }
  119.  
  120.   procedure set_date_from_server;
  121.   { pulls the date from the server and updates the workstation's clock }
  122.  
  123.   procedure set_time_from_server;
  124.   { pulls the time from the server and updates the workstation's clock }
  125.  
  126.   procedure get_server_version(var _version : string);
  127.   procedure open_message_pipe(var _connection, error: integer);
  128.   procedure close_message_pipe(var _connection, error: integer);
  129.   procedure check_message_pipe(var _connection, error: integer);
  130.  
  131.   procedure send_personal_message(
  132.     var _connection : integer; var _message : string; var error : integer
  133.   );
  134.  
  135.   procedure get_personal_message(
  136.     var _connection : integer; var _message : string; var error : integer
  137.   );
  138.  
  139.   procedure get_drive_connection_id(var drive_number, server_number : integer);
  140.   { pass the drive number - it returns the server number if a network volume }
  141.  
  142.   procedure get_file_server_name(
  143.     var server_number: integer; var server_name: string
  144.   );
  145.  
  146.   procedure get_directory_path(
  147.     var handle: integer; var pathname: string; var error: integer
  148.   );
  149.  
  150.   procedure get_drive_handle_id(var drive_number, handle_number: integer);
  151.  
  152.   procedure set_preferred_connection_id(server_num: integer);
  153.   procedure get_preferred_connection_id(var server_num: integer);
  154.   procedure set_primary_connection_id(server_num: integer);
  155.   procedure get_primary_connection_id(var server_num: integer);
  156.   procedure get_default_connection_id(var server_num: integer);
  157.  
  158.   procedure get_internet_address(
  159.     station : integer;
  160.     var net_number, node_addr, socket_number : string;
  161.     var error : integer
  162.   );
  163.  
  164.   procedure login_to_file_server(
  165.     obj_type: integer; _name, _password: string; var error: integer
  166.   );
  167.  
  168.   procedure logout;
  169.   procedure logout_from_file_server(var id: integer);
  170.   procedure down_file_server(flag: integer; var error: integer);
  171.   procedure detach_from_file_server(var id, error: integer);
  172.   procedure disable_file_server_login(var error: integer);
  173.   procedure enable_file_server_login(var error: integer);
  174.  
  175.   procedure alloc_permanent_directory_handle(
  176.     var _dir_handle       : integer;
  177.     var _drive_letter     :  string;
  178.     var _dir_path_name    :  string;
  179.     var _new_dir_handle   : integer;
  180.     var _effective_rights :    byte;
  181.     var _error            : integer
  182.   );
  183.  
  184.   procedure map(var drive_spec: string; var _rights: byte; var _error: integer);
  185.  
  186.   procedure scan_object(
  187.     var last_object        : longint;
  188.     var search_object_type : integer;
  189.     var search_object      :  string;
  190.     var replyid            : longint;
  191.     var replytype          : integer;
  192.     var replyname          :  string;
  193.     var replyflag          : integer;
  194.     var replysecurity      :    byte;
  195.     var replyproperties    : integer;
  196.     var error              : integer
  197.   );
  198.  
  199.   procedure verify_object_password(
  200.     var object_type:integer; var object_name, password : string;
  201.     var error : integer
  202.   );
  203.  
  204.  
  205.   { file locking routines }
  206.  
  207.   procedure log_file(
  208.     lock_directive:integer; log_filename: string;
  209.     log_timeout:integer; var error:integer
  210.   );
  211.  
  212.   procedure clear_file_set;
  213.   procedure lock_file_set(lock_timeout:integer; var error:integer);
  214.   procedure release_file_set;
  215.   procedure release_file(log_filename: string; var error:integer);
  216.   procedure clear_file(log_filename: string; var error:integer);
  217.  
  218.  
  219.  
  220.   procedure open_semaphore(
  221.     _name           :   string;
  222.     _initial_value  : shortint;
  223.     var _open_count :  integer;
  224.     var _handle     :  longint;
  225.     var error       :  integer
  226.   );
  227.  
  228.   procedure close_semaphore(var _handle:longint; var error:integer);
  229.   procedure examine_semaphore(
  230.     var _handle:longint; var _value:shortint; var _count, error:integer
  231.   );
  232.   procedure signal_semaphore(var _handle:longint; var error:integer);
  233.   procedure wait_on_semaphore(
  234.     var _handle:longint; _timeout:integer; var error:integer
  235.   );
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249. implementation
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256.  
  257.  
  258.  
  259. const
  260.   zero = '0';
  261.  
  262.  
  263. var
  264.   error : word; { return code for all functions }
  265.  
  266.  
  267.  
  268.   
  269.   {
  270.     pulls volume names from default server.  use set_preferred_connection_id
  271.     to set the default server.
  272.     errors:  0=ok, 1=no volume assigned  98h= # out of range
  273.   }
  274.   procedure get_volume_name;
  275.   var
  276.     pcregs        : registers;
  277.     count, count1  : integer;
  278.  
  279.     requestbuffer : record
  280.       len         : integer;
  281.       func        :    byte;
  282.       vol_num     :    byte;
  283.     end;
  284.  
  285.     replybuffer : record
  286.       len         : integer;
  287.       vol_length  : byte;
  288.       name        : array[1..16] of byte;
  289.     end;
  290.  
  291.   begin
  292.     with pcregs do begin
  293.       ah := $e2;
  294.       ds := seg(requestbuffer);
  295.       si := ofs(requestbuffer);
  296.       es := seg(replybuffer);
  297.       di := ofs(replybuffer);
  298.     end;
  299.     with requestbuffer do begin
  300.       len  := 2;
  301.       func := 6;
  302.       vol_num := volume_number;  {passed from calling program}
  303.     end;
  304.     with replybuffer do begin
  305.       len :=  17;
  306.       vol_length := 0;
  307.       for count := 1 to 16 do name[count] := $00;
  308.     end;
  309.     msdos(pcregs);
  310.     volume_name := '';
  311.     if replybuffer.vol_length > 0 then 
  312.       for count := 1 to replybuffer.vol_length do
  313.         volume_name := volume_name + chr(replybuffer.name[count]);
  314.     error := pcregs.al;
  315.   end;
  316.  
  317.  
  318.   
  319.   procedure verify_object_password;
  320.   {
  321.     for netware 3.xx remember to have previously (eg in the autoexec file )
  322.     set allow unencrypted passwords = on
  323.     on the console, otherwise this call always fails !
  324.     note that intruder lockout status is affected by this call !
  325.     netware security isn't that stupid....
  326.     passwords appear to need to be converted to upper case
  327.  
  328.     error      apparent meaning as far as i can work out....
  329.  
  330.       0            verification of object_name/password combination
  331.       197          account disabled due to intrusion lockout
  332.       214          unencrypted password calls not allowed on this v3+ server
  333.       252          no such object_name on this server
  334.       255          failure to verify object_name/password combination
  335.   }
  336.   var
  337.     regs : registers;
  338.  
  339.     request_buffer : record
  340.       buffer_length   :               integer;
  341.       dosfn           :                  byte;
  342.       obj_type        :   array[1..2] of byte;
  343.       obj_name_length :                  byte;
  344.       obj_name        :  array[1..47] of byte;
  345.       password_length :                  byte;
  346.       obj_password    : array[1..127] of byte;
  347.     end;
  348.  
  349.     reply_buffer : record
  350.       buffer_length : integer;
  351.     end;
  352.  
  353.     count : integer;
  354.  
  355.   begin
  356.     with request_buffer do begin
  357.       buffer_length := 179;
  358.       dosfn := $3f;
  359.       obj_type[1] := 0;
  360.       obj_type[2] := object_type;
  361.       obj_name_length := 47;
  362.       for count := 1 to 47 do obj_name[count] := $00;
  363.       for count := 1 to length(object_name) do 
  364.         obj_name[count] := ord(object_name[count]);
  365.       password_length := length(password);
  366.       for count := 1 to 127 do obj_password[count] := $00;
  367.       if password_length > 0 then for count := 1 to password_length do
  368.         obj_password[count] := ord(upcase(password[count]));
  369.     end;
  370.     with reply_buffer do buffer_length := 0;
  371.     with regs do begin
  372.       ah := $e3;
  373.       ds := seg(request_buffer);
  374.       si := ofs(request_buffer);
  375.       es := seg(reply_buffer);
  376.       di := ofs(reply_buffer);
  377.     end;
  378.     msdos(regs);
  379.     error := regs.al;
  380.   end; { verify_object_password }
  381.  
  382.  
  383.  
  384.   procedure scan_object;
  385.   var
  386.     regs : registers;
  387.  
  388.     request_buffer : record
  389.       buffer_length :              integer;
  390.       dosfn         :                 byte;
  391.       last_seen     :              longint;
  392.       search_type   :  array[1..2] of byte;
  393.       name_length   :                 byte;
  394.       search_name   : array[1..47] of byte;
  395.     end;
  396.  
  397.     reply_buffer : record
  398.       buffer_length :              integer;
  399.       object_id     :              longint;
  400.       object_type   :  array[1..2] of byte;
  401.       object_name   : array[1..48] of byte;
  402.       object_flag   :                 byte;
  403.       security      :                 byte;
  404.       properties    :                 byte;
  405.     end;
  406.  
  407.     count : integer;
  408.  
  409.   begin
  410.     with request_buffer do begin
  411.       buffer_length := 55;
  412.       dosfn := $37;
  413.       last_seen := last_object;
  414.       if search_object_type = -1 then { -1 = wildcard } begin
  415.         search_type[1] := $ff;
  416.         search_type[2] := $ff;
  417.       end else begin
  418.         search_type[1] := 0;
  419.         search_type[2] := search_object_type;
  420.       end;
  421.       name_length := length(search_object);
  422.       for count := 1 to 47 do search_name[count] := $00;
  423.       if name_length > 0 then for count := 1 to name_length do
  424.         search_name[count] := ord(upcase(search_object[count]));
  425.     end;
  426.     with reply_buffer do begin
  427.       buffer_length := 57;
  428.       object_id := 0;
  429.       object_type[1] := 0;
  430.       object_type[2] := 0;
  431.       for count := 1 to 48 do object_name[count] := $00;
  432.       object_flag := 0;
  433.       security := 0;
  434.       properties := 0;
  435.     end;
  436.     with regs do begin
  437.       ah := $e3;
  438.       ds := seg(request_buffer);
  439.       si := ofs(request_buffer);
  440.       es := seg(reply_buffer);
  441.       di := ofs(reply_buffer);
  442.     end;
  443.     msdos(regs);
  444.     error := regs.al;
  445.     with reply_buffer do begin
  446.       replyflag := object_flag;
  447.       replyproperties := properties;
  448.       replysecurity := security;
  449.       replytype := object_type[2];
  450.       replyid := object_id;
  451.     end;
  452.     count := 1;
  453.     replyname := '';
  454.     while (count <= 48)  and (reply_buffer.object_name[count] <> 0) do begin
  455.       replyname := replyname + chr(reply_buffer.object_name[count]);
  456.       count := count + 1;
  457.     end { while };
  458.   end;
  459.  
  460.  
  461.  
  462.   procedure alloc_permanent_directory_handle;
  463.   var
  464.     regs : registers;
  465.  
  466.     request_buffer : record
  467.       buffer_length   : integer;
  468.       dosfn           : byte;
  469.       dir_handle      : byte;
  470.       drive_letter    : byte;
  471.       dir_path_length : byte;
  472.       dir_path_name   : packed array[1..255] of byte;
  473.     end;
  474.  
  475.     reply_buffer : record
  476.       buffer_length    : integer;
  477.       new_dir_handle   :    byte;
  478.       effective_rights :    byte;
  479.     end;
  480.  
  481.     count : integer;
  482.  
  483.   begin
  484.     with request_buffer do begin
  485.       buffer_length := 259;
  486.       dosfn := $12;
  487.       dir_handle := _dir_handle;
  488.       drive_letter := ord(upcase(_drive_letter[1]));
  489.       dir_path_length := length(_dir_path_name);
  490.       for count := 1 to 255 do dir_path_name[count] := $0;
  491.       if dir_path_length > 0 then for count := 1 to dir_path_length do
  492.       dir_path_name[count] := ord(upcase(_dir_path_name[count]));
  493.     end;
  494.     with reply_buffer do begin
  495.       buffer_length := 2;
  496.       new_dir_handle := 0;
  497.       effective_rights := 0;
  498.     end;
  499.     with regs do begin
  500.       ah := $e2;
  501.       ds := seg(request_buffer);
  502.       si := ofs(request_buffer);
  503.       es := seg(reply_buffer);
  504.       di := ofs(reply_buffer);
  505.     end;
  506.     msdos(regs);
  507.     _error := regs.al;
  508.     _effective_rights := $0;
  509.     _new_dir_handle := $0;
  510.     if _error = 0 then begin
  511.       _effective_rights := reply_buffer.effective_rights;
  512.       _new_dir_handle := reply_buffer.new_dir_handle;
  513.     end;
  514.   end;
  515.  
  516.  
  517.  
  518.  
  519.   procedure map;
  520.   var
  521.     dir_handle   : integer;
  522.     path_name    :  string;
  523.     rights       :    byte;
  524.     drive_number : integer;
  525.     drive_letter :  string;
  526.     new_handle   : integer;
  527.     error        : integer;
  528.  
  529.   begin
  530.     {first thing is we strip leading and trailing blanks}
  531.     while drive_spec[1]=' ' do
  532.       drive_spec := copy(drive_spec, 2, length(drive_spec));
  533.     while drive_spec[length(drive_spec)]=' ' do
  534.       drive_spec := copy(drive_spec, 1, length(drive_spec)-1);
  535.     drive_number := ord(upcase(drive_spec[1]))-65;
  536.     drive_letter := upcase(drive_spec[1]);
  537.     path_name := copy(drive_spec, 4, length(drive_spec));
  538.     get_drive_handle_id(drive_number, dir_handle);
  539.     alloc_permanent_directory_handle(
  540.       dir_handle, drive_letter, path_name, new_handle, rights, error
  541.     );
  542.     _error := error;
  543.     _rights := rights;
  544.   end;
  545.  
  546.  
  547.  
  548.  
  549.   procedure down_file_server;
  550.   var
  551.     regs : registers;
  552.  
  553.     request_buffer : record
  554.       buffer_length : integer;
  555.       dosfn         :    byte;
  556.       down_flag     :    byte;
  557.     end;
  558.  
  559.     reply_buffer : record
  560.       buffer_length : integer;
  561.     end;
  562.  
  563.   begin
  564.     with request_buffer do begin
  565.       buffer_length := 2;
  566.       dosfn := $d3;
  567.       down_flag := flag;
  568.     end;
  569.     reply_buffer.buffer_length := 0;
  570.     with regs do begin
  571.       ah := $e3;
  572.       ds := seg(request_buffer);
  573.       si := ofs(request_buffer);
  574.       es := seg(reply_buffer);
  575.       di := ofs(reply_buffer);
  576.     end;
  577.     msdos(regs);
  578.     error := regs.al;
  579.   end;
  580.  
  581.  
  582.  
  583.  
  584.   procedure set_preferred_connection_id;
  585.   var regs : registers;
  586.   begin
  587.     regs.ah := $f0;
  588.     regs.al := $00;
  589.     regs.dl := server_num;
  590.     msdos(regs);
  591.   end;
  592.  
  593.  
  594.  
  595.  
  596.   procedure set_primary_connection_id;
  597.   var regs : registers;
  598.   begin
  599.     regs.ah := $f0;
  600.     regs.al := $04;
  601.     regs.dl := server_num;
  602.     msdos(regs);
  603.   end;
  604.  
  605.  
  606.  
  607.  
  608.   procedure get_primary_connection_id;
  609.   var regs : registers;
  610.   begin
  611.     regs.ah := $f0;
  612.     regs.al := $05;
  613.     msdos(regs);
  614.     server_num := regs.al;
  615.   end;
  616.  
  617.  
  618.  
  619.  
  620.   procedure get_default_connection_id;
  621.   var regs : registers;
  622.   begin
  623.     regs.ah := $f0;
  624.     regs.al := $02;
  625.     msdos(regs);
  626.     server_num := regs.al;
  627.   end;
  628.  
  629.  
  630.  
  631.  
  632.   procedure get_preferred_connection_id;
  633.   var regs : registers;
  634.   begin
  635.     regs.ah := $f0;
  636.     regs.al := $02;
  637.     msdos(regs);
  638.     server_num := regs.al;
  639.   end;
  640.  
  641.  
  642.  
  643.  
  644.   procedure get_drive_connection_id;
  645.   var
  646.     regs        :            registers;
  647.     drive_table : array[1..32] of byte;
  648.     count       :              integer;
  649.     p           :                ^byte;
  650.  
  651.   begin
  652.     regs.ah := $ef;
  653.     regs.al := $02;
  654.     msdos(regs);
  655.     p := ptr(regs.es, regs.si);
  656.     move(p^, drive_table, 32);
  657.     if ((drive_number < 0) or (drive_number > 32))  then drive_number := 1;
  658.     server_number := drive_table[drive_number];
  659.   end;
  660.  
  661.  
  662.  
  663.  
  664.   procedure get_drive_handle_id;
  665.   var
  666.     regs        :            registers;
  667.     drive_table : array[1..32] of byte;
  668.     count       :              integer;
  669.     p           :                ^byte;
  670.  
  671.   begin
  672.     regs.ah := $ef;
  673.     regs.al := $00;
  674.     msdos(regs);
  675.     p := ptr(regs.es, regs.si);
  676.     move(p^, drive_table, 32);
  677.     if ((drive_number < 0) or (drive_number > 32))  then drive_number := 1;
  678.     handle_number := drive_table[drive_number];
  679.   end;
  680.  
  681.  
  682.  
  683.  
  684.   procedure get_file_server_name;
  685.   var
  686.     regs       :              registers;
  687.     name_table : array[1..8*48] of byte;
  688.     server     :  array[1..8] of string;
  689.     count      :                integer;
  690.     count2     :                integer;
  691.     p          :                  ^byte;
  692.     no_more    :                integer;
  693.  
  694.   begin
  695.     regs.ah := $EF; regs.al := $04; msdos(regs);
  696.     no_more := 0; p := ptr(regs.es, regs.si);
  697.     move(p^, name_table, 8*48);
  698.     for count := 1 to 8 do server[count] := '';
  699.     for count := 0 to 7 do begin
  700.       no_more := 0;
  701.       for count2 := (count*48)+1 to (count*48)+48 do
  702.         if name_table[count2] <> $00 then begin
  703.           if no_more=0 then server[count+1] := server[count+1] + 
  704.             chr(name_table[count2]);
  705.         end else no_more := 1; {scan until 00h is found}
  706.     end;
  707.     if ((server_number<1) or (server_number>8)) then server_number := 1;
  708.     server_name := server[server_number];
  709.   end;
  710.  
  711.  
  712.  
  713.  
  714.   procedure disable_file_server_login;
  715.   var
  716.     regs : registers;
  717.  
  718.     request_buffer : record
  719.       buffer_length : integer;
  720.       dosfn         :    byte
  721.     end;
  722.  
  723.     reply_buffer : record
  724.       buffer_length : integer;
  725.     end;
  726.  
  727.   begin
  728.     with regs do begin
  729.       ah := $e3;
  730.       ds := seg(request_buffer);
  731.       si := ofs(request_buffer);
  732.       es := seg(reply_buffer);
  733.       di := ofs(reply_buffer);
  734.     end;
  735.     with request_buffer do begin
  736.       buffer_length := 1;
  737.       dosfn := $cb;
  738.     end;
  739.     reply_buffer.buffer_length := 0;
  740.     msdos(regs);
  741.     error := regs.al;
  742.   end;
  743.  
  744.  
  745.  
  746.  
  747.   procedure enable_file_server_login;
  748.   var
  749.     regs : registers;
  750.  
  751.     request_buffer : record
  752.       buffer_length : integer;
  753.       dosfn         :    byte
  754.     end;
  755.  
  756.     reply_buffer : record
  757.       buffer_length : integer;
  758.     end;
  759.  
  760.   begin
  761.     with regs do begin
  762.       ah := $e3;
  763.       ds := seg(request_buffer);
  764.       si := ofs(request_buffer);
  765.       es := seg(reply_buffer);
  766.       di := ofs(reply_buffer);
  767.     end;
  768.     with request_buffer do begin
  769.       buffer_length := 1;
  770.       dosfn := $cc;
  771.     end;
  772.     reply_buffer.buffer_length := 0;
  773.     msdos(regs);
  774.     error := regs.al;
  775.   end;
  776.  
  777.  
  778.  
  779.  
  780.   procedure get_directory_path;
  781.   var
  782.     regs  : registers;
  783.     count :   integer;
  784.  
  785.     request_buffer : record
  786.       len        : integer;
  787.       dosfn      :    byte;
  788.       dir_handle :    byte;
  789.     end;
  790.  
  791.     reply_buffer : record
  792.       len       :               integer;
  793.       path_len  :                  byte;
  794.       path_name : array[1..255] of byte;
  795.     end;
  796.  
  797.   begin
  798.     with regs do begin
  799.       ah := $e2;
  800.       ds := seg(request_buffer);
  801.       si := ofs(request_buffer);
  802.       es := seg(reply_buffer);
  803.       di := ofs(reply_buffer);
  804.     end;
  805.     with request_buffer do begin
  806.       len := 2;
  807.       dosfn := $01;
  808.       dir_handle := handle;
  809.     end;
  810.     with reply_buffer do begin
  811.       len := 256;
  812.       path_len := 0;
  813.       for count := 1 to 255 do path_name[count] := $00;
  814.     end;
  815.     msdos(regs);
  816.     error := regs.al;
  817.     pathname := '';
  818.     if reply_buffer.path_len > 0 then for count := 1 to reply_buffer.path_len do
  819.       pathname := pathname + chr(reply_buffer.path_name[count]);
  820.   end;
  821.  
  822.  
  823.  
  824.  
  825.   procedure detach_from_file_server;
  826.   var regs : registers;
  827.   begin
  828.     regs.ah := $f1;
  829.     regs.al := $01;
  830.     regs.dl := id;
  831.     msdos(regs);
  832.     error := regs.al;
  833.   end;
  834.  
  835.  
  836.  
  837.  
  838.   procedure getstation;
  839.   var
  840.     pcregs : registers;
  841.  
  842.   begin
  843.     pcregs.ah := $dc;
  844.     msdos( pcregs );
  845.     _station := pcregs.al;
  846.     error := 0;
  847.   end;
  848.  
  849.  
  850.  
  851.  
  852.   procedure gethexid;
  853.   var
  854.     reg           : registers;
  855.     i, x           :   integer;
  856.     hex_id        :    string;
  857.  
  858.     requestbuffer : record
  859.       len      :              integer;
  860.       func     :                 byte;
  861.       conntype :  array[1..2] of byte;
  862.       name_len :                 byte;
  863.       name     : array[1..47] of char;
  864.     end;
  865.  
  866.     replybuffer : record
  867.       len       :              integer;
  868.       uniqueid1 :  array[1..2] of byte;
  869.       uniqueid2 :  array[1..2] of byte;
  870.       conntype  :                 word;
  871.       name      : array[1..48] of byte;
  872.     end;
  873.  
  874.   begin
  875.     reg.ah := $e3;
  876.     requestbuffer.func := $35;
  877.     reg.ds := seg(requestbuffer);
  878.     reg.si := ofs(requestbuffer);
  879.     reg.es := seg(replybuffer);
  880.     reg.di := ofs(replybuffer);
  881.     requestbuffer.len := 52;
  882.     replybuffer.len := 55;
  883.     requestbuffer.name_len := length(userid);
  884.     for i := 1 to length(userid) do requestbuffer.name[i] := userid[i];
  885.     requestbuffer.conntype[2] := $1;
  886.     requestbuffer.conntype[1] := $0;
  887.     replybuffer.conntype := 1;
  888.     msdos(reg);
  889.     error := reg.al;   {
  890.     if error = $96 then writeln('server out of memory');
  891.     if error = $ef then writeln('invalid name');
  892.     if error = $f0 then writeln('wildcard not allowed');
  893.     if error = $fc then writeln('no such object *', userid, '*');
  894.     if error = $fe then writeln('server bindery locked');
  895.     if error = $ff then writeln('bindery failure'); }
  896.     hex_id := '';
  897.     if error = 0 then begin
  898.       hex_id := hexdigits[replybuffer.uniqueid1[1] shr 4];
  899.       hex_id := hex_id + hexdigits[replybuffer.uniqueid1[1] and $0f];
  900.       hex_id := hex_id + hexdigits[replybuffer.uniqueid1[2] shr 4];
  901.       hex_id := hex_id + hexdigits[replybuffer.uniqueid1[2] and $0f];
  902.       hex_id := hex_id + hexdigits[replybuffer.uniqueid2[1] shr 4];
  903.       hex_id := hex_id + hexdigits[replybuffer.uniqueid2[1] and $0f];
  904.       hex_id := hex_id + hexdigits[replybuffer.uniqueid2[2] shr 4];
  905.       hex_id := hex_id + hexdigits[replybuffer.uniqueid2[2] and $0f];
  906.       { now we chop off leading zeros }
  907.       while hex_id[1] = '0' do hex_id := copy(hex_id, 2, length(hex_id));
  908.     end;
  909.     hexid := hex_id;
  910.   end;
  911.  
  912.  
  913.  
  914.   
  915.   procedure getconnectioninfo;
  916.   var
  917.     reg            : registers;
  918.     i, x            : integer;
  919.     requestbuffer : record
  920.       packetlength : integer;
  921.       functionval  : byte;
  922.       connectionno : byte;
  923.     end;
  924.     replybuffer : record
  925.       returnlength :              integer;
  926.       uniqueid1    :  array[1..2] of byte;
  927.       uniqueid2    :  array[1..2] of byte;
  928.       conntype     :  array[1..2] of byte;
  929.       objectname   : array[1..48] of byte;
  930.       logintime    :  array[1..8] of byte;
  931.     end;
  932.     month          : string[3];
  933.     year, 
  934.     day, 
  935.     hour, 
  936.     minute         : string[2];
  937.  
  938.   begin
  939.     with requestbuffer do begin
  940.       packetlength := 2;
  941.       functionval := 22;  { 22 = get station info }
  942.       connectionno := logicalstationno;
  943.     end;
  944.     replybuffer.returnlength := 62;
  945.     with reg do begin
  946.       ah := $e3;
  947.       ds := seg(requestbuffer);
  948.       si := ofs(requestbuffer);
  949.       es := seg(replybuffer);
  950.       di := ofs(replybuffer);
  951.     end;
  952.     msdos(reg);
  953.     name := '';
  954.     hex_id := '';
  955.     conntype := 0;
  956.     datetime := '';
  957.     if reg.al = 0 then begin
  958.       with replybuffer do begin
  959.         i := 1;
  960.         while (i <= 48)  and (objectname[i] <> 0) do begin
  961.           name[i] := chr(objectname[i]);
  962.           inc(i);
  963.         end { while };
  964.         name[0] := chr(i - 1);
  965.         if name<>'' then begin
  966.           str(logintime[1]:2, year);
  967.           month := months[logintime[2]];
  968.           str(logintime[3]:2, day);
  969.           str(logintime[4]:2, hour);
  970.           str(logintime[5]:2, minute);
  971.           if day[1] = ' ' then day[1] := '0';
  972.           if hour[1] = ' ' then hour[1] := '0';
  973.           if minute[1] = ' ' then minute[1] := '0';
  974.           datetime := day + ' ' + month + ' ' + year +
  975.             '  ' + hour + ':' + minute;
  976.         end;
  977.       end { with };
  978.     end;
  979.     error := reg.al;
  980.     if name<>'' then begin
  981.       hex_id := '';
  982.       hex_id := hexdigits[replybuffer.uniqueid1[1] shr 4];
  983.       hex_id := hex_id + hexdigits[replybuffer.uniqueid1[1] and $0f];
  984.       hex_id := hex_id + hexdigits[replybuffer.uniqueid1[2] shr 4];
  985.       hex_id := hex_id + hexdigits[replybuffer.uniqueid1[2] and $0f];
  986.       hex_id := hex_id + hexdigits[replybuffer.uniqueid2[1] shr 4];
  987.       hex_id := hex_id + hexdigits[replybuffer.uniqueid2[1] and $0f];
  988.       hex_id := hex_id + hexdigits[replybuffer.uniqueid2[2] shr 4];
  989.       hex_id := hex_id + hexdigits[replybuffer.uniqueid2[2] and $0f];
  990.       conntype := replybuffer.conntype[2];
  991.       { now we chop off leading zeros }
  992.       while (hex_id[1]='0') and (length(hex_id) > 0) do
  993.         hex_id := copy(hex_id, 2, length(hex_id));
  994.     end;
  995.   end { getconnectinfo };
  996.  
  997.  
  998.  
  999.  
  1000.   procedure login_to_file_server;
  1001.   var
  1002.     regs : registers;
  1003.  
  1004.     request_buffer : record
  1005.       b_length        :              integer;
  1006.       dosfn           :                 byte;
  1007.       o_type          :  array[1..2] of byte;
  1008.       name_length     :                 byte;
  1009.       obj_name        : array[1..47] of byte;
  1010.       password_length :                 byte;
  1011.       password        : array[1..27] of byte;
  1012.     end;
  1013.  
  1014.     reply_buffer : record
  1015.       r_length : integer;
  1016.     end;
  1017.  
  1018.     count : integer;
  1019.  
  1020.   begin
  1021.     with request_buffer do begin
  1022.       b_length := 79;
  1023.       dosfn := $14;
  1024.       o_type[1] := 0;
  1025.       o_type[2] := obj_type;
  1026.       for count := 1 to 47 do obj_name[count] := $0;
  1027.       for count := 1 to 27 do password[count] := $0;
  1028.       if length(_name) > 0 then for count := 1 to length(_name) do
  1029.         obj_name[count] := ord(upcase(_name[count]));
  1030.       if length(_password) > 0 then for count := 1 to length(_password) do
  1031.         password[count] := ord(upcase(_password[count]));
  1032.       {set to full length of field}
  1033.       name_length := 47;
  1034.       password_length := 27;
  1035.     end;
  1036.     with reply_buffer do begin
  1037.       r_length := 0;
  1038.     end;
  1039.     with regs do begin
  1040.       ah := $e3;
  1041.       ds := seg(request_buffer);
  1042.       si := ofs(request_buffer);
  1043.       es := seg(reply_buffer);
  1044.       di := ofs(reply_buffer);
  1045.     end;
  1046.     msdos(regs);
  1047.     error := regs.al
  1048.   end;
  1049.  
  1050.  
  1051.  
  1052.  
  1053.   procedure logout;
  1054.   {logout from all file servers}
  1055.   var regs : registers;
  1056.   begin
  1057.     regs.ah := $d7;
  1058.     msdos(regs);
  1059.   end;
  1060.  
  1061.  
  1062.  
  1063.  
  1064.   procedure logout_from_file_server;
  1065.   {logout from one file server}
  1066.   var regs : registers;
  1067.   begin
  1068.     regs.ah := $f1;
  1069.     regs.al := $02;
  1070.     regs.dl := id;
  1071.     msdos(regs);
  1072.   end;
  1073.  
  1074.  
  1075.  
  1076.  
  1077.   procedure send_message_to_username;
  1078.   var
  1079.     count1     :    byte;
  1080.     userid     :  string;
  1081.     stationid  : integer;
  1082.     ret_code   : integer;
  1083.  
  1084.   begin
  1085.     ret_code := 1;
  1086.     for count1 := 1 to length(username) do
  1087.       username[count1] := upcase(username[count1]); { convert to upper case }
  1088.     getserverinfo;
  1089.     for count1 := 1 to serverinfo.connections_max do begin
  1090.       stationid := count1;
  1091.       getuser( stationid, userid, error);
  1092.       if userid = username then begin
  1093.         ret_code := 0;
  1094.         send_message_to_station(stationid, message, error);
  1095.       end;
  1096.     end; { end of count }
  1097.     error := ret_code;
  1098.     { error = 0 if sent,  1 if userid not found }
  1099.   end; { end of procedure }
  1100.  
  1101.  
  1102.  
  1103.  
  1104.   procedure getserverinfo;
  1105.   var
  1106.     reg            : registers;
  1107.     requestbuffer : record
  1108.       packetlength : integer;
  1109.       functionval  :    byte;
  1110.     end;
  1111.     i              :   integer;
  1112.  
  1113.   begin
  1114.     with requestbuffer do begin
  1115.       packetlength := 1;
  1116.       functionval := 17;  { 17 = get server info }
  1117.     end;
  1118.     serverinfo.returnlength := 128;
  1119.     with reg do begin
  1120.       ah := $e3;
  1121.       ds := seg(requestbuffer);
  1122.       si := ofs(requestbuffer);
  1123.       es := seg(serverinfo);
  1124.       di := ofs(serverinfo);
  1125.     end;
  1126.     msdos(reg);
  1127.     with serverinfo do begin
  1128.       connections_max := connectionmax[1]*256 + connectionmax[2];
  1129.       connections_in_use := connectionuse[1]*256 + connectionuse[2];
  1130.       max_connected_volumes := maxconvol[1]*256 + maxconvol[2];
  1131.       peak_connections_used := peak_used[1]*256 + peak_used[2];
  1132.       name := '';
  1133.       i := 1;
  1134.       while ((server[i] <> 0) and (i<>48)) do begin
  1135.         name := name + chr(server[i]);
  1136.         inc(i);
  1137.       end;
  1138.     end;
  1139.   end;
  1140.  
  1141.  
  1142.  
  1143.  
  1144.   procedure getservername;
  1145.   { this routine returns the same as getserverinfo.  this routine   }
  1146.   { was kept to maintain compatibility with the older  novell unit. }
  1147.   begin
  1148.     getserverinfo;
  1149.     servername := serverinfo.name;
  1150.     error := 0;
  1151.   end;
  1152.  
  1153.  
  1154.  
  1155.  
  1156.   
  1157.   procedure send_message_to_station;
  1158.   var
  1159.     pcregs : registers;
  1160.  
  1161.     req_buffer : record
  1162.       buffer_len :              integer;
  1163.       dosfn      :                 byte;
  1164.       c_count    :                 byte;
  1165.       c_list     :                 byte;
  1166.       msg_length :                 byte;
  1167.       msg        : array[1..55] of byte;
  1168.     end;
  1169.  
  1170.     rep_buffer : record
  1171.       buffer_len : integer;
  1172.       c_count    :    byte;
  1173.       r_list     :    byte;
  1174.     end;
  1175.  
  1176.     count1 : integer;
  1177.  
  1178.   begin
  1179.     if length(message) > 55 then message := copy(message, 1, 55);
  1180.     with pcregs do begin
  1181.       ah := $e1;
  1182.       ds := seg(req_buffer);
  1183.       si := ofs(req_buffer);
  1184.       es := seg(rep_buffer);
  1185.       di := ofs(rep_buffer);
  1186.     end;
  1187.     with req_buffer do begin
  1188.       buffer_len := 59;
  1189.       dosfn := 00;
  1190.       c_count := 1;
  1191.       c_list := station;
  1192.       for count1 := 1 to 55 do msg[count1] := $00; { zero the buffer }
  1193.       msg_length := length(message); { message length }
  1194.       for count1 := 1 to length(message) do msg[count1] := ord(message[count1]);
  1195.     end;
  1196.     with rep_buffer do begin
  1197.       buffer_len := 2;
  1198.       c_count := 1;
  1199.       r_list := 0;
  1200.     end;
  1201.     msdos( pcregs );
  1202.     error := rep_buffer.r_list;
  1203.   end;
  1204.  
  1205.  
  1206.  
  1207.  
  1208.  
  1209.   
  1210.   procedure getuser;
  1211.   {this procedure provides a shorter method of obtaining just the userid.}
  1212.   var
  1213.     gu_hexid    :  string;
  1214.     gu_conntype : integer;
  1215.     gu_datetime :  string;
  1216.  
  1217.   begin
  1218.     getconnectioninfo(
  1219.       _station, _username, gu_hexid, gu_conntype, gu_datetime, error
  1220.     );
  1221.   end;
  1222.  
  1223.  
  1224.  
  1225.  
  1226.   
  1227.   procedure getnode;
  1228.   { get the physical station address }
  1229.   const
  1230.     hex_set : array[0..15] of char = '0123456789ABCDEF';
  1231.  
  1232.   var
  1233.     regs : registers;
  1234.  
  1235.   begin { getnode }
  1236.     {get the physical address from the network card}
  1237.     regs.ah := $ee;
  1238.     msdos(regs);
  1239.     hex_addr := '';
  1240.     hex_addr := hex_addr + hex_set[(regs.ch shr 4)];
  1241.     hex_addr := hex_addr + hex_set[(regs.ch and $0f)];
  1242.     hex_addr := hex_addr + hex_set[(regs.cl shr 4) ];
  1243.     hex_addr := hex_addr + hex_set[(regs.cl and $0f)];
  1244.     hex_addr := hex_addr + hex_set[(regs.bh shr 4)];
  1245.     hex_addr := hex_addr + hex_set[(regs.bh and $0f)];
  1246.     hex_addr := hex_addr + hex_set[(regs.bl shr 4)];
  1247.     hex_addr := hex_addr + hex_set[(regs.bl and $0f)];
  1248.     hex_addr := hex_addr + hex_set[(regs.ah shr 4)];
  1249.     hex_addr := hex_addr + hex_set[(regs.ah and $0f)];
  1250.     hex_addr := hex_addr + hex_set[(regs.al shr 4)];
  1251.     hex_addr := hex_addr + hex_set[(regs.al and $0f)];
  1252.     error := 0;
  1253.   end; { getnode }
  1254.  
  1255.  
  1256.  
  1257.   procedure get_internet_address;
  1258.   const
  1259.     hex_set : array[0..15] of char = '0123456789ABCDEF';
  1260.  
  1261.   var
  1262.     regs : registers;
  1263.  
  1264.     request_buffer : record
  1265.       length     : integer;
  1266.       dosfn      :    byte;
  1267.       connection :    byte;
  1268.     end;
  1269.  
  1270.     reply_buffer : record
  1271.       length  :             integer;
  1272.       network : array[1..4] of byte;
  1273.       node    : array[1..6] of byte;
  1274.       socket  : array[1..2] of byte;
  1275.     end;
  1276.  
  1277.     count          : integer;
  1278.     _node_addr     :  string;
  1279.     _socket_number :  string;
  1280.     _net_number    :  string;
  1281.  
  1282.   begin
  1283.     with regs do begin
  1284.       ah := $e3;
  1285.       ds := seg(request_buffer);
  1286.       si := ofs(request_buffer);
  1287.       es := seg(reply_buffer);
  1288.       di := ofs(reply_buffer);
  1289.     end;
  1290.     with request_buffer do begin
  1291.       length := 2;
  1292.       dosfn := $13;
  1293.       connection := station;
  1294.     end;
  1295.     with reply_buffer do begin
  1296.       length := 12;
  1297.       for count := 1 to 4 do network[count] := 0;
  1298.       for count := 1 to 6 do node[count] := 0;
  1299.       for count := 1 to 2 do socket[count] := 0;
  1300.     end;
  1301.     msdos(regs);
  1302.     error := regs.al;
  1303.     _net_number := '';
  1304.     _node_addr := '';
  1305.     _socket_number := '';
  1306.     if error = 0 then begin
  1307.       for count := 1 to 4 do begin
  1308.         _net_number := _net_number + hex_set[
  1309.           (reply_buffer.network[count] shr 4)
  1310.         ];
  1311.         _net_number := _net_number + hex_set[
  1312.           (reply_buffer.network[count] and $0f)
  1313.         ];
  1314.       end;
  1315.       for count := 1 to 6 do begin
  1316.         _node_addr := _node_addr + (hex_set[
  1317.           (reply_buffer.node[count] shr 4) 
  1318.         ]);
  1319.         _node_addr := _node_addr + (hex_set[
  1320.           (reply_buffer.node[count] and $0f)
  1321.         ]);
  1322.       end;
  1323.       for count := 1 to 2 do begin
  1324.         _socket_number := _socket_number + (hex_set[
  1325.           (reply_buffer.socket[count] shr 4)
  1326.         ]);
  1327.        _socket_number := _socket_number + (hex_set[
  1328.           (reply_buffer.socket[count] and $0f)
  1329.         ]);
  1330.       end;
  1331.     end; {end of error=0}
  1332.     net_number := _net_number;
  1333.     node_addr := _node_addr;
  1334.     socket_number := _socket_number;
  1335.   end;
  1336.  
  1337.  
  1338.  
  1339.  
  1340.   
  1341.   procedure get_realname;
  1342.   var
  1343.     requestbuffer : record
  1344.       buffer_length : array[1..2] of byte;
  1345.       dosfn           :                 byte;
  1346.       object_type     :  array[1..2] of byte;
  1347.       object_length   :                 byte;
  1348.       object_name     : array[1..47] of byte;
  1349.       segment         :                 byte;
  1350.       property_length :                 byte;
  1351.       property_name   : array[1..14] of byte;
  1352.     end;
  1353.  
  1354.     replybuffer : record
  1355.       buffer_length  :   array[1..2] of byte;
  1356.       property_value : array[1..128] of byte;
  1357.       more_segments  :                  byte;
  1358.       property_flags :                  byte;
  1359.     end;
  1360.  
  1361.     count    :   integer;
  1362.     id       :    string;
  1363.     regs     : registers;
  1364.     fullname :    string;
  1365.  
  1366.   begin
  1367.     id := 'identification';
  1368.     with requestbuffer do begin
  1369.       buffer_length[2] := 0;
  1370.       buffer_length[1] := 69;
  1371.       dosfn  := $3d;
  1372.       object_type[1] := 0;
  1373.       object_type[2] := 01;
  1374.       segment := 1;
  1375.       object_length := 47;
  1376.       property_length := length(id);
  1377.       for count := 1 to 47 do object_name[count] := $0;
  1378.       for count := 1 to length(userid) do
  1379.         object_name[count] := ord(userid[count]);
  1380.       for count := 1 to 14 do property_name[count] := $0;
  1381.       for count := 1 to length(id) do property_name[count] := ord(id[count]);
  1382.     end;
  1383.     with replybuffer do begin
  1384.       buffer_length[1] := 130;
  1385.       buffer_length[2] := 0;
  1386.       for count := 1 to 128 do property_value[count] := $0;
  1387.       more_segments := 1;
  1388.       property_flags := 0;
  1389.     end;
  1390.     with regs do begin
  1391.       ah := $e3;
  1392.       ds := seg(requestbuffer);
  1393.       si := ofs(requestbuffer);
  1394.       es := seg(replybuffer);
  1395.       di := ofs(replybuffer);
  1396.     end;
  1397.     msdos(regs);
  1398.     error := regs.al;
  1399.     fullname := '';
  1400.     count := 1;
  1401.     repeat
  1402.       if replybuffer.property_value[count] <> 0 then
  1403.         fullname := fullname + chr(replybuffer.property_value[count]);
  1404.       inc(count);
  1405.     until ((count = 128) or (replybuffer.property_value[count] = 0));
  1406.     {if regs.al = $96 then writeln('server out of memory');
  1407.     if regs.al = $ec then writeln('no such segment');
  1408.     if regs.al = $f0 then writeln('wilcard not allowed');
  1409.     if regs.al = $f1 then writeln('invalid bindery security');
  1410.     if regs.al = $f9 then writeln('no property read priv');
  1411.     if regs.al = $fb then writeln('no such property');
  1412.     if regs.al = $fc then writeln('no such object');}
  1413.     if error=0 then realname := fullname else realname := '';
  1414.   end;
  1415.  
  1416.  
  1417.  
  1418.  
  1419.   
  1420.   procedure get_broadcast_mode;
  1421.   var regs : registers;
  1422.   begin
  1423.     regs.ah := $de;
  1424.     regs.dl := $04;
  1425.     msdos(regs);
  1426.     bmode := regs.al;
  1427.   end;
  1428.  
  1429.  
  1430.  
  1431.   procedure set_broadcast_mode;
  1432.   var regs : registers;
  1433.   begin
  1434.     if ((bmode > 3) or (bmode < 0)) then bmode := 0;
  1435.     regs.ah := $de;
  1436.     regs.dl := bmode;
  1437.     msdos(regs);
  1438.     bmode := regs.al;
  1439.   end;
  1440.  
  1441.  
  1442.  
  1443.  
  1444.   procedure get_broadcast_message;
  1445.   var
  1446.     regs : registers;
  1447.  
  1448.     requestbuffer : record
  1449.       bufferlength : array[1..2] of byte;
  1450.       dosfn        :                byte;
  1451.     end;
  1452.  
  1453.     replybuffer : record
  1454.       bufferlength  :  array[1..2] of byte;
  1455.       messagelength :                 byte;
  1456.       message       : array[1..58] of byte;
  1457.     end;
  1458.  
  1459.     count : integer;
  1460.  
  1461.   begin
  1462.     with requestbuffer do begin
  1463.        bufferlength[1] := 1;
  1464.        bufferlength[2] := 0;
  1465.        dosfn := 1;
  1466.     end;
  1467.     with replybuffer do begin
  1468.       bufferlength[1] := 59;
  1469.       bufferlength[2] := 0;
  1470.       messagelength := 0;
  1471.     end;
  1472.     for count := 1 to 58 do replybuffer.message[count] := $0;
  1473.     with regs do begin
  1474.       ah := $e1;
  1475.       ds := seg(requestbuffer);
  1476.       si := ofs(requestbuffer);
  1477.       es := seg(replybuffer);
  1478.       di := ofs(replybuffer);
  1479.     end;
  1480.     msdos(regs);
  1481.     error := regs.al;
  1482.     bmessage := '';
  1483.     count := 0;
  1484.     if replybuffer.messagelength > 58 then replybuffer.messagelength := 58;
  1485.     if replybuffer.messagelength > 0 then
  1486.       for count := 1 to replybuffer.messagelength do
  1487.         bmessage := bmessage + chr(replybuffer.message[count]);
  1488.         { error = 0 if no message,  1 if message was retreived }
  1489.     if length(bmessage) = 0 then error := 1 else error := 0;
  1490.   end;
  1491.  
  1492.  
  1493.   
  1494.  
  1495.   
  1496.   procedure get_server_datetime;
  1497.   var
  1498.     replybuffer : record
  1499.       year : byte;
  1500.       month : byte;
  1501.       day : byte;
  1502.       hour : byte;
  1503.       minute : byte;
  1504.       second : byte;
  1505.       dow : byte;
  1506.     end;
  1507.     regs : registers;
  1508.  
  1509.   begin
  1510.     with regs do begin
  1511.       ah := $e7;
  1512.       ds := seg(replybuffer);
  1513.       dx := ofs(replybuffer);
  1514.     end;
  1515.     msdos(regs);
  1516.     error := regs.al;
  1517.     _year := replybuffer.year;
  1518.     _month := replybuffer.month;
  1519.     _day := replybuffer.day;
  1520.     _hour := replybuffer.hour;
  1521.     _min := replybuffer.minute;
  1522.     _sec := replybuffer.second;
  1523.     _dow := replybuffer.dow;
  1524.   end;
  1525.  
  1526.  
  1527.  
  1528.   
  1529.   procedure set_date_from_server;
  1530.   var
  1531.     replybuffer : record
  1532.       year, month, day, 
  1533.       hour, minute, 
  1534.       second, dow  : byte;
  1535.     end;
  1536.     regs : registers;
  1537.  
  1538.   begin
  1539.     with regs do begin
  1540.       ah := $e7;
  1541.       ds := seg(replybuffer);
  1542.       dx := ofs(replybuffer);
  1543.     end;
  1544.     msdos(regs);
  1545.     setdate(replybuffer.year+1900, replybuffer.month, replybuffer.day);
  1546.   end;
  1547.  
  1548.  
  1549.  
  1550.  
  1551.   
  1552.   procedure set_time_from_server;
  1553.   var
  1554.     replybuffer : record
  1555.       year, month, day, 
  1556.       hour, minute, 
  1557.       second, dow  : byte;
  1558.     end;
  1559.     regs : registers;
  1560.  
  1561.   begin
  1562.     with regs do begin
  1563.       ah := $e7;
  1564.       ds := seg(replybuffer);
  1565.       dx := ofs(replybuffer);
  1566.     end;
  1567.     msdos(regs);
  1568.     settime(replybuffer.hour, replybuffer.minute, replybuffer.second, 0);
  1569.   end;
  1570.  
  1571.  
  1572.  
  1573.  
  1574.   
  1575.   procedure get_server_version;
  1576.   var
  1577.     regs : registers;
  1578.     count, x : integer;
  1579.     request_buffer : record
  1580.       buffer_length : integer;
  1581.       dosfn         :    byte;
  1582.     end;
  1583.  
  1584.     reply_buffer : record
  1585.       buffer_length :               integer;
  1586.       stuff         : array[1..512] of byte;
  1587.     end;
  1588.  
  1589.     strings : array[1..3] of string;
  1590.  
  1591.   begin
  1592.     with regs do begin
  1593.       ah := $e3;
  1594.       ds := seg(request_buffer);
  1595.       si := ofs(request_buffer);
  1596.       es := seg(reply_buffer);
  1597.       di := ofs(reply_buffer);
  1598.     end;
  1599.     with request_buffer do begin
  1600.       buffer_length := 1;
  1601.       dosfn := $c9;
  1602.     end;
  1603.     with reply_buffer do begin
  1604.       buffer_length := 512;
  1605.       for count := 1 to 512 do stuff[count] := $00;
  1606.     end;
  1607.     msdos(regs);
  1608.     for count := 1 to 3 do strings[count] := '';
  1609.     x := 1;
  1610.     with reply_buffer do begin
  1611.       for count := 1 to 256 do begin
  1612.         if stuff[count] <> $0 then begin
  1613.           if not(
  1614.             (stuff[count]=32) and (strings[x]='')
  1615.           ) then strings[x] := strings[x] + chr(stuff[count]);
  1616.         end;
  1617.         if stuff[count] = $0 then if x <> 3 then inc(x);
  1618.       end;
  1619.     end; { end of with }
  1620.     _version := strings[2];
  1621.   end;
  1622.  
  1623.  
  1624.  
  1625.  
  1626.   
  1627.   procedure open_message_pipe;
  1628.   var
  1629.     regs : registers;
  1630.  
  1631.     request_buffer : record
  1632.       buffer_length    : integer;
  1633.       dosfn            :    byte;
  1634.       connection_count :    byte;
  1635.       connection_list  :    byte;
  1636.     end;
  1637.  
  1638.     reply_buffer : record
  1639.       buffer_length    : integer;
  1640.       connection_count :    byte;
  1641.       result_list      :    byte;
  1642.     end;
  1643.  
  1644.   begin
  1645.     with regs do begin
  1646.       ah := $e1;
  1647.       ds := seg(request_buffer);
  1648.       si := ofs(request_buffer);
  1649.       es := seg(reply_buffer);
  1650.       di := ofs(reply_buffer);
  1651.     end;
  1652.     with request_buffer do begin
  1653.       buffer_length := 3;
  1654.       dosfn := $06;
  1655.       connection_count := $01;
  1656.       connection_list := _connection;
  1657.     end;
  1658.     with reply_buffer do begin
  1659.       buffer_length := 2;
  1660.       connection_count := 0;
  1661.       result_list := 0;
  1662.     end;
  1663.     msdos(regs);
  1664.     error := reply_buffer.result_list;
  1665.   end;
  1666.  
  1667.  
  1668.  
  1669.  
  1670.   procedure close_message_pipe;
  1671.   var
  1672.     regs : registers;
  1673.  
  1674.     request_buffer : record
  1675.       buffer_length    : integer;
  1676.       dosfn            :    byte;
  1677.       connection_count :    byte;
  1678.       connection_list  :    byte;
  1679.     end;
  1680.  
  1681.     reply_buffer : record
  1682.       buffer_length : integer;
  1683.       connection_count : byte;
  1684.       result_list : byte;
  1685.     end;
  1686.  
  1687.   begin
  1688.     with regs do begin
  1689.       ah := $e1;
  1690.       ds := seg(request_buffer);
  1691.       si := ofs(request_buffer);
  1692.       es := seg(reply_buffer);
  1693.       di := ofs(reply_buffer);
  1694.     end;
  1695.     with request_buffer do begin
  1696.       buffer_length := 3;
  1697.       dosfn := $07;
  1698.       connection_count := $01;
  1699.       connection_list := _connection;
  1700.     end;
  1701.     with reply_buffer do begin
  1702.       buffer_length := 2;
  1703.       connection_count := 0;
  1704.       result_list := 0;
  1705.     end;
  1706.     msdos(regs);
  1707.     error := reply_buffer.result_list;
  1708.   end;
  1709.  
  1710.  
  1711.  
  1712.  
  1713.   
  1714.   procedure check_message_pipe;
  1715.   var
  1716.     regs : registers;
  1717.  
  1718.     request_buffer : record
  1719.       buffer_length    : integer;
  1720.       dosfn            :    byte;
  1721.       connection_count :    byte;
  1722.       connection_list  :    byte;
  1723.     end;
  1724.  
  1725.     reply_buffer : record
  1726.       buffer_length    : integer;
  1727.       connection_count :    byte;
  1728.       result_list      :    byte;
  1729.     end;
  1730.  
  1731.   begin
  1732.     with regs do begin
  1733.       ah := $e1;
  1734.       ds := seg(request_buffer);
  1735.       si := ofs(request_buffer);
  1736.       es := seg(reply_buffer);
  1737.       di := ofs(reply_buffer);
  1738.     end;
  1739.     with request_buffer do begin
  1740.       buffer_length := 3;
  1741.       dosfn := $08;
  1742.       connection_count := $01;
  1743.       connection_list := _connection;
  1744.     end;
  1745.     with reply_buffer do begin
  1746.       buffer_length := 2;
  1747.       connection_count := 0;
  1748.       result_list := 0;
  1749.     end;
  1750.     msdos(regs);
  1751.     error := reply_buffer.result_list;
  1752.   end;
  1753.  
  1754.  
  1755.  
  1756.  
  1757.   
  1758.   
  1759.   procedure send_personal_message;
  1760.   var
  1761.     regs  : registers;
  1762.     count :   integer;
  1763.  
  1764.     request_buffer : record
  1765.       buffer_length : integer;
  1766.       dosfn,           
  1767.       connection_count, 
  1768.       connection_list, 
  1769.       message_length   :                  byte;
  1770.       message          : array[1..126] of byte;
  1771.     end;
  1772.  
  1773.     reply_buffer : record
  1774.       buffer_length    : integer;
  1775.       connection_count :    byte;
  1776.       result_list      :    byte;
  1777.     end;
  1778.  
  1779.   begin
  1780.     with regs do begin
  1781.       ah := $e1;
  1782.       ds := seg(request_buffer);
  1783.       si := ofs(request_buffer);
  1784.       es := seg(reply_buffer);
  1785.       di := ofs(reply_buffer);
  1786.     end;
  1787.     with request_buffer do begin
  1788.       dosfn := $04;
  1789.       connection_count := $01;
  1790.       connection_list := _connection;
  1791.       message_length := length(_message);
  1792.       buffer_length := length(_message) + 4;
  1793.       for count := 1 to 126 do message[count] := $00;
  1794.       if message_length > 0 then for count := 1 to message_length do
  1795.         message[count] := ord(_message[count]);
  1796.     end;
  1797.     with reply_buffer do begin
  1798.       buffer_length := 2;
  1799.       connection_count := 0;
  1800.       result_list := 0;
  1801.     end;
  1802.     msdos(regs);
  1803.     error := reply_buffer.result_list;
  1804.   end;
  1805.  
  1806.  
  1807.  
  1808.  
  1809.  
  1810.   
  1811.   procedure get_personal_message;
  1812.   var
  1813.     regs  : registers;
  1814.     count :  integer;
  1815.  
  1816.     request_buffer : record
  1817.       buffer_length : integer;
  1818.       dosfn         :   byte;
  1819.     end;                
  1820.  
  1821.     reply_buffer : record
  1822.       buffer_length     :               integer;
  1823.       source_connection :                  byte;
  1824.       message_length    :                  byte;
  1825.       message_buffer    : array[1..126] of byte;
  1826.     end;
  1827.  
  1828.   begin
  1829.     with regs do begin
  1830.       ah := $e1;
  1831.       ds := seg(request_buffer);
  1832.       si := ofs(request_buffer);
  1833.       es := seg(reply_buffer);
  1834.       di := ofs(reply_buffer);
  1835.     end;
  1836.     with request_buffer do begin
  1837.       buffer_length := 1;
  1838.       dosfn := $05;
  1839.     end;
  1840.     with reply_buffer do begin
  1841.       buffer_length := 128;
  1842.       source_connection := 0;
  1843.       message_length := 0;
  1844.       for count := 1 to 126 do message_buffer[count] := $0;
  1845.     end;
  1846.     msdos(regs);
  1847.     _connection := reply_buffer.source_connection;
  1848.     _message := '';
  1849.     error := reply_buffer.message_length;
  1850.     if error > 0 then for count := 1 to error do
  1851.       _message := _message + chr(reply_buffer.message_buffer[count]);
  1852.   end;
  1853.  
  1854.  
  1855.  
  1856.  
  1857.  
  1858.   procedure log_file;
  1859.   var regs : registers;
  1860.   begin
  1861.     with regs do begin
  1862.       ah := $eb;
  1863.       ds := seg(log_filename);
  1864.       dx := ofs(log_filename);
  1865.       bp := log_timeout;
  1866.     end;
  1867.     msdos(regs);
  1868.     error := regs.al;
  1869.   end;
  1870.  
  1871.  
  1872.  
  1873.  
  1874.   
  1875.   procedure release_file;
  1876.   var regs : registers;
  1877.   begin
  1878.     with regs do begin
  1879.       ah := $ec;
  1880.       ds := seg(log_filename);
  1881.       dx := ofs(log_filename);
  1882.     end;
  1883.     msdos(regs);
  1884.     error := regs.al;
  1885.   end;
  1886.  
  1887.  
  1888.  
  1889.  
  1890.   
  1891.   procedure clear_file;
  1892.   var regs : registers;
  1893.   begin
  1894.     with regs do begin
  1895.       ah := $ed;
  1896.       ds := seg(log_filename);
  1897.       dx := ofs(log_filename);
  1898.     end;
  1899.     msdos(regs);
  1900.     error := regs.al;
  1901.   end;
  1902.  
  1903.  
  1904.  
  1905.  
  1906.   
  1907.   procedure clear_file_set;
  1908.   var regs : registers;
  1909.   begin
  1910.     regs.ah := $cf;
  1911.     msdos(regs);
  1912.     error := regs.al;
  1913.   end;
  1914.  
  1915.  
  1916.  
  1917.  
  1918.   
  1919.   procedure lock_file_set;
  1920.   var regs : registers;
  1921.   begin
  1922.     regs.ah := $cb;
  1923.     regs.bp := lock_timeout;
  1924.     msdos(regs);
  1925.     error := regs.al;
  1926.   end;
  1927.  
  1928.  
  1929.  
  1930.  
  1931.   
  1932.   procedure release_file_set;
  1933.   var regs : registers;
  1934.   begin
  1935.     regs.ah := $cd;
  1936.     msdos(regs);
  1937.   end;
  1938.  
  1939.  
  1940.  
  1941.  
  1942.   
  1943.   procedure open_semaphore;
  1944.   var
  1945.     regs             :             registers;
  1946.     s_name           : array[1..129] of byte;
  1947.     count            :               integer;
  1948.     semaphore_handle :  array[1..2] of word;
  1949.  
  1950.   begin
  1951.     if (_initial_value < 0) or (_initial_value > 127) then _initial_value := 0;
  1952.     for count := 1 to 129 do s_name[count] := $00; {zero buffer}
  1953.     if length(_name) > 127 then _name := copy(_name, 1, 127); {limit name length}
  1954.     if length(_name) > 0 then for count := 1 to length(_name) do
  1955.       s_name[count+1] := ord(_name[count]);
  1956.     s_name[1] := length(_name);
  1957.     regs.ah := $c5;
  1958.     regs.al := $00;
  1959.     move(_initial_value, regs.cl, 1);
  1960.     regs.ds := seg(s_name);
  1961.     regs.dx := ofs(s_name);
  1962.     msdos(regs);
  1963.     error := regs.al;
  1964.     _open_count := regs.bl;
  1965.     semaphore_handle[1] := regs.cx;
  1966.     semaphore_handle[2] := regs.dx;
  1967.     move(semaphore_handle, _handle, 4);
  1968.   end;
  1969.  
  1970.  
  1971.  
  1972.  
  1973.   
  1974.   procedure close_semaphore;
  1975.   var
  1976.     regs             :           registers;
  1977.     semaphore_handle : array[1..2] of word;
  1978.  
  1979.   begin
  1980.     move(_handle, semaphore_handle, 4);
  1981.     regs.ah := $c5;
  1982.     regs.al := $04;
  1983.     regs.cx := semaphore_handle[1];
  1984.     regs.dx := semaphore_handle[2];
  1985.     msdos(regs);
  1986.     error := regs.al;  { 00h=successful   ffh=invalid handle}
  1987.   end;
  1988.  
  1989.  
  1990.  
  1991.  
  1992.   
  1993.   procedure examine_semaphore;
  1994.   var
  1995.     regs             :           registers;
  1996.     semaphore_handle : array[1..2] of word;
  1997.  
  1998.   begin
  1999.     move(_handle, semaphore_handle, 4);
  2000.     regs.ah := $c5;
  2001.     regs.al := $01;
  2002.     regs.cx := semaphore_handle[1];
  2003.     regs.dx := semaphore_handle[2];
  2004.     msdos(regs);
  2005.     error := regs.al; {00h=successful ffh=invalid handle}
  2006.     move(regs.cx, _value, 1);
  2007.     _count := regs.dl;
  2008.   end;
  2009.  
  2010.  
  2011.  
  2012.  
  2013.   
  2014.   procedure signal_semaphore;
  2015.   var
  2016.     regs             :           registers;
  2017.     semaphore_handle : array[1..2] of word;
  2018.  
  2019.   begin
  2020.     move(_handle, semaphore_handle, 4);
  2021.     regs.ah := $c5;
  2022.     regs.al := $03;
  2023.     regs.cx := semaphore_handle[1];
  2024.     regs.dx := semaphore_handle[2];
  2025.     msdos(regs);
  2026.     error := regs.al;
  2027.     {00h=successful   01h=overflow value > 127   ffh=invalid handle}
  2028.   end;
  2029.  
  2030.  
  2031.  
  2032.  
  2033.   
  2034.   procedure wait_on_semaphore;
  2035.   var
  2036.     regs             :           registers;
  2037.     semaphore_handle : array[1..2] of word;
  2038.  
  2039.   begin
  2040.     move(_handle, semaphore_handle, 4);
  2041.     regs.ah := $c5;
  2042.     regs.al := $02;
  2043.     regs.bp := _timeout; {units in 1/18 of second,   0 = no wait}
  2044.     regs.cx := semaphore_handle[1];
  2045.     regs.dx := semaphore_handle[2];
  2046.     msdos(regs);
  2047.     error := regs.al;
  2048.     {00h=successful   feh=timeout failure   ffh=invalid handle}
  2049.   end;
  2050.  
  2051.  
  2052.  
  2053.  
  2054.   
  2055.   procedure clear_connection;
  2056.   var 
  2057.     con_num :      byte;
  2058.     regs    : registers;
  2059.  
  2060.     request_buffer : record
  2061.       length  : integer;
  2062.       dosfn   :    byte;
  2063.       con_num :    byte;
  2064.     end;
  2065.  
  2066.     reply_buffer : record
  2067.       length : integer;
  2068.     end;
  2069.  
  2070.   begin
  2071.     with request_buffer do begin
  2072.       length := 4;
  2073.       con_num := connection_number;
  2074.       dosfn := $d2;
  2075.     end;
  2076.     reply_buffer.length := 0;
  2077.     with regs do begin
  2078.       ah := $e3;
  2079.       ds := seg(request_buffer);
  2080.       si := ofs(request_buffer);
  2081.       es := seg(reply_buffer);
  2082.       di := ofs(reply_buffer);
  2083.     end;
  2084.     msdos(regs);
  2085.     error := regs.al;
  2086.   end;
  2087.  
  2088.  
  2089.  
  2090. end. { end of unit novell }
  2091.  
  2092.  
  2093. this unit provides a method of obtaining novell information from a user
  2094. written program.  this unit was tested on an ibm at running dos 4.0 &  
  2095. using netware 2.15.  the unit compiled cleanly under turbo pascal 6.0  
  2096.                                                                        
  2097. last update:   8 apr 91                                                
  2098. -----------------------------------------------------------------------
  2099.                                                                        
  2100. any questions can be directed to:                                      
  2101.                                                                        
  2102. mark bramwell                                                          
  2103. university of western ontario                                          
  2104. london, ontario, n6a 3k7                                               
  2105.                                                                        
  2106. phone:  519-473-3618 [work]              519-473-3618 [home]           
  2107.                                                                        
  2108. bitnet: mark@hamster.business.uwo.ca     packet: ve3pzr @ ve3gyq       
  2109.                                                                        
  2110. anonymous ftp server internet address: 129.100.22.100                  
  2111.                                                                        
  2112. -----------------------------------------------------------------------
  2113.  
  2114.  
  2115. mods february 1 1991, ross lazarus (rml@extro.ucc.su.au.oz)
  2116.      var errors in procedure getservername, get_broadcast_message, 
  2117.      verify_object_password comments, password conversion to upper case, 
  2118.  
  2119. seems to work fine on a netware 3.00 and on 3.01 servers -
  2120.  
  2121. -----------------------------------------------------------------------
  2122.