home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Pascal / Snippets / PNL Libraries / MyOldSIVC.p < prev    next >
Encoding:
Text File  |  1996-09-26  |  13.1 KB  |  541 lines  |  [TEXT/CWIE]

  1. unit MyOldSIVC;
  2.  
  3. interface
  4.  
  5.     uses
  6.         Types;
  7.  
  8.     const
  9.         PC_UseSIVC = 'SIVC';
  10.         PC_FirstCheckSIVC = 'SIVd';
  11.         PC_LastCheckSIVCQuantum = 'SICl';
  12.         PC_CheckSIVCPeriod = 'SIVc';
  13.         PC_LastSIVC = 'SIVL';
  14.         PC_SIVCUsers = 'SIVU';
  15.         
  16.     type
  17.         SIVCNewVersionCallBack = procedure(data:Handle; latest_version:Str31; where: Str255);
  18.         SIVCGetSOCKSServerCallBack = procedure(const forhost: Str255; var server:Str255);
  19.         SIVCManualQueryCallBack = procedure(err:OSErr; newversion, usingsocks:Boolean; data:Handle; latest_version:Str31; where: Str255);
  20.     
  21.     var
  22.         first_ever_sivc: Boolean; { if this is the first time - warn the user! }
  23.         
  24.     procedure StartupSIVC;
  25.     procedure ConfigureSIVC(newversion : SIVCNewVersionCallBack; getsocks:SIVCGetSOCKSServerCallBack);
  26.         
  27.     procedure ManualQuery(mqresult: SIVCManualQueryCallBack);
  28.     function CanManualQuery:Boolean;
  29.     
  30. implementation
  31.  
  32.     uses
  33.         Resources, Errors, 
  34.         MyVersionResource, MyStartup, TCPOOConnections, MyNewPreferences, MyUtils,
  35.         MySocks, MyTranslateISO, MyMemory, MyHandleFile,
  36.         PrefCodes;
  37.         
  38.     const
  39.         sivc_id = 932;
  40.         sivc_default_port = 7124;
  41.         idle_til_period = 10 * 60 *60; { only even consider checking every 10 minutes }
  42.  
  43.     type
  44.         SIVCStrings = (SS_None, SS_Server, SS_SOCKSServer, SS_Where);
  45.         SIVCStates = (ST_None, ST_Doing, ST_Finished);
  46.         ManualStates = (MS_None, MS_Want, MS_Doing);
  47.  
  48.     var
  49.         manual_state: ManualStates;
  50.         sivc_state: SIVCStates;
  51.         mqresult_callback: SIVCManualQueryCallBack;
  52.         newversion_callback: SIVCNewVersionCallBack;
  53.         getsocks_callback: SIVCGetSOCKSServerCallBack;
  54.         vers:versionRecord;
  55.         app_creator: string[4];
  56.         idle_til: longint;
  57.         sivc_host: Str255;
  58.         sivc_port:integer;
  59.  
  60.     procedure CallManualResult(err:OSErr; newversion, usingsocks:Boolean; data:Handle; latest_version:Str31; where: Str255);
  61.     begin
  62.         if (manual_state = MS_Doing) & (mqresult_callback <> nil) then begin
  63.             mqresult_callback( err, newversion, usingsocks, data, latest_version, where );
  64.             mqresult_callback := nil;
  65.             manual_state := MS_None;
  66.         end;
  67.     end;
  68.     
  69.     procedure CallManualResultError( err: OSErr; usingsocks: boolean );
  70.     begin
  71.         CallManualResult( err, false, usingsocks, nil, '', '' );
  72.     end;
  73.     
  74.     function GetThisQuantum:longint;
  75.         var
  76.             date,first_checked_date,check_period: longint;
  77.     begin
  78.         GetDateTime(date);
  79.         prefs.GetTagLong(PC_FirstCheckSIVC,first_checked_date);
  80.         prefs.GetTagLong(PC_CheckSIVCPeriod,check_period);
  81.         GetThisQuantum := (date - first_checked_date) div 60 div check_period;
  82.     end;
  83.     
  84.     procedure GetSOCKSServer( const forhost: Str255; var server:Str255 );
  85.     begin
  86.         server := '';
  87.         if getsocks_callback <> nil then begin
  88.             getsocks_callback( forhost, server );
  89.         end;
  90.         if server = '' then begin
  91.             GetIndString( server, sivc_id, ord(SS_SOCKSServer) );
  92.         end;
  93.     end;
  94.     
  95.     procedure ServerToHostPort(s:Str255; defport:integer; var host:Str255; var port:integer);
  96.         var
  97.             portstr:Str255;
  98.             n:longint;
  99.     begin
  100.         if SplitAt(s, ':', host, portstr) | SplitAt(s, ' ', host, portstr) then begin
  101.             StringToNum(portstr,n);
  102.             port := n;
  103.         end else begin
  104.             host := s;
  105.             port := defport;
  106.         end;
  107.     end;
  108.     
  109.     function IsField(field:Str255; var line:Str255):Boolean;
  110.         var
  111.             s:Str255;
  112.     begin
  113.         IsField := false;
  114.         if IsPrefix(line, field) then begin
  115.             s := Trim(TPcopy(line, length(field)+1, 255));
  116.             if (s<>'') & (s[1] = ':') then begin
  117.                 line := Trim(TPcopy(s, 2, 255));
  118.                 IsField := true;
  119.             end;
  120.         end;
  121.     end;
  122.     
  123.     type
  124.         SIVCConnection = object(LineConnectionObject)
  125.             use_socks: boolean;
  126.             sivc_ip: longint;
  127.             query_result: Handle;
  128.             procedure Established;
  129.             override;
  130.             function Create: OSErr;
  131.             override;
  132.             procedure Destroy;
  133.             override;
  134.             procedure Failed (oe: OSErr);
  135.             override;
  136.             procedure CharsAvailable( count: longint );
  137.             override;
  138.             procedure Closing;
  139.             override;
  140.             procedure Send( data: Ptr; len: integer );
  141.             procedure SendQuery;
  142.             procedure SendSocks;
  143.             procedure ProcessResult;
  144.             procedure Receive( data: Ptr; len: integer );
  145.         end;
  146.         SIVCLookup = object(AddressSearchObject)
  147.             procedure Destroy;
  148.             override;
  149.             procedure FoundAddress (ip: longint);
  150.             override;
  151.             procedure Failed (oe: OSErr);
  152.             override;
  153.         end;    
  154.     
  155.     var
  156.         conn_obj: SIVCConnection;
  157.         lookup_obj:SIVCLookup;
  158.     
  159.     function SIVCConnection.Create: OSErr;
  160.     begin
  161.         query_result := NewHandle( 0 );
  162.         Create := inherited Create;
  163.     end;
  164.     
  165.     procedure SIVCConnection.Destroy;
  166.     begin
  167.         conn_obj := nil;
  168.         idle_til := TickCount + idle_til_period;
  169.         sivc_state := ST_None;
  170.         MDisposeHandle( query_result );
  171.         inherited Destroy;
  172.     end;
  173.     
  174.     procedure SIVCLookup.Destroy;
  175.     begin
  176.         lookup_obj := nil;
  177.         idle_til := TickCount + idle_til_period;
  178.         inherited Destroy;
  179.     end;
  180.     
  181.     procedure SIVCLookup.FoundAddress (ip: longint);
  182.         var
  183.             s: Str255;
  184.             socks_port: integer;
  185.     begin
  186.         new(conn_obj);
  187.         conn_obj.use_socks := true;
  188.         conn_obj.sivc_ip := ip;
  189.         GetSOCKSServer( sivc_host, s );
  190.         ServerToHostPort(s, socks_default_port, s, socks_port);
  191.         conn_obj.NewActiveConnection( 0, s, socks_port );
  192.     end;
  193.  
  194.     procedure SIVCLookup.Failed (oe: OSErr);
  195.     begin
  196.         CallManualResultError( oe, true );
  197.         sivc_state := ST_None;
  198.         inherited Failed( oe );
  199.     end;
  200.  
  201.     procedure SIVCConnection.Failed (oe: OSErr);
  202.     begin
  203.         CallManualResultError( oe, use_socks );
  204.         inherited Failed( oe );
  205.     end;
  206.  
  207.     procedure SIVCConnection.Send( data: Ptr; len: integer );
  208.         var
  209.             err: OSErr;
  210.     begin
  211.         err := TCPSendAsync( tcpc, data, len, true, nil);
  212.         if ( err <> noErr ) then begin
  213.             Failed( err );
  214.         end;
  215.     end;
  216.     
  217.     procedure SIVCConnection.Receive( data: Ptr; len: integer );
  218.         var
  219.             err: OSErr;
  220.     begin
  221.         err := TCPRawReceiveChars( tcpc, data, len );
  222.         if ( err <> noErr ) then begin
  223.             Failed( err );
  224.         end;
  225.     end;
  226.     
  227.     procedure SIVCConnection.SendQuery;
  228.         var
  229.             query:Str255;
  230.             count:integer;
  231.     begin
  232.         if (manual_state = MS_Doing) then begin
  233.             query := 'Query: ProductInfoManual';
  234.         end else begin
  235.             query := 'Query: ProductInfoAuto';
  236.         end;
  237.         query := concat(query, cr,
  238.                                 'Product: ', vers.name, cr,
  239.                                 'ProductID: macos:APPL/',app_creator,cr,
  240.                                 'Version: ',HexNN(longint(vers.numericVersion),8),cr,
  241.                                 cr);
  242.         count := MacToNet(@query[1],length(query));
  243.         
  244.         Send( @query[1], count);
  245.     end;
  246.  
  247.     procedure SIVCConnection.SendSocks;
  248.         var
  249.             query:SocksRecord;
  250.             len: longint;
  251.     begin
  252.         query.version := socks_version;
  253.         query.cmd := socks_connect;
  254.         query.port := sivc_port;
  255.         query.ip := sivc_ip;
  256.         query.name := concat('AnarchieSIVC', chr(0));
  257.         len := SizeOf(SocksRecordSmall) + length(query.name);
  258.         BlockMoveData(@query.name[1], @query.name, length(query.name));
  259.         Send( @query, len );
  260.     end;
  261.     
  262.     procedure SIVCConnection.Established;
  263.     begin
  264.         timeout_time := TickCount + 60*60*2;
  265.         if ( use_socks ) then begin
  266.             SendSocks;
  267.         end else begin
  268.             SendQuery;
  269.         end;
  270.     end;
  271.     
  272.     procedure SIVCConnection.CharsAvailable( count: longint );
  273.         var
  274.             size: longint;
  275.             socksresult:SocksRecordSmall;
  276.             err: OSErr;
  277.     begin
  278.         if ( use_socks ) then begin
  279.             if count >= SizeOf(socksresult) then begin
  280.                 Receive( @socksresult, SizeOf(socksresult) );
  281.                 if not timetodie & (socksresult.cmd <> socks_result) then begin
  282.                     Failed( -2 );
  283.                 end;
  284.                 if not timetodie then begin
  285.                     use_socks := false;
  286.                     SendQuery;
  287.                 end;
  288.             end;
  289.         end else begin
  290.             size := GetHandleSize( query_result );
  291.             err := MSetHandleSize( query_result, size + count );
  292.             if ( err <> noErr ) then begin
  293.                 Failed( err );
  294.             end else begin
  295.                 HLock( query_result );
  296.                 Receive( Ptr(longint(query_result^) + size), count );
  297.                 HUnlock( query_result );
  298.             end;
  299.         end;
  300.     end;
  301.     
  302.     procedure SIVCConnection.ProcessResult;
  303.         var
  304.             hf:HandleFile;
  305.             line:Str255;
  306.             where: Str255;
  307.             latest_version:longint;
  308.             query_interval, users:longint;
  309.             ver:NumVersion;
  310.             new:boolean;
  311.             gotversion: boolean;
  312.     begin
  313.         hf.data := query_result;
  314.         hf.pos := 0;
  315.         hf.crlf := CL_CR;
  316.         hf.error := noErr;
  317.         latest_version := -1;
  318.         GetIndString( where, sivc_id, ord(SS_Where) );
  319.         gotversion := false;
  320.         while ReadFromHandleFile(hf, line) do begin
  321.             if IsField('ReleaseVersion', line) then begin
  322.                 latest_version := HexToNum(line);
  323.                 gotversion := true;
  324.             end else if IsField('AutoQueryIntervalM', line) then begin
  325.                 StringToNum(line, query_interval);
  326.                 if (query_interval >= 1440) & (query_interval < 136800) then begin { 1 to 95 days }
  327.                     prefs.SetTagLong(PC_CheckSIVCPeriod, query_interval);
  328.                 end;
  329.             end else if IsField('UserCount',line) then begin
  330.                 StringToNum(line, users);
  331.                 prefs.SetTagLong(PC_SIVCUsers, users);
  332.             end else if IsField( 'ReleaseURL', line ) then begin
  333.                 where := line;
  334.             end;
  335.         end;
  336.         new := (latest_version > longint(vers.numericVersion));
  337.         line := '';
  338.         if (latest_version <> -1) then begin
  339.             ver := NumVersion(latest_version);
  340.             line:=concat(NumToStr(ver.majorRev),'.',
  341.                                 NumToStr(BAND(ver.minorAndBugRev div 16,$0F)),'.',
  342.                                 NumToStr(BAND(ver.minorAndBugRev,$0F))
  343.                                 );
  344.             if (ver.stage<>$80) or (ver.nonRelRev<>0) then begin
  345.                 case ver.stage of 
  346.                     $20:begin
  347.                         line:=concat(line,'d');
  348.                     end;
  349.                     $40:begin
  350.                         line:=concat(line,'a');
  351.                     end;
  352.                     $60:begin
  353.                         line:=concat(line,'b');
  354.                     end;
  355.                     $80:begin
  356.                         line:=concat(line,'f');
  357.                     end;
  358.                     otherwise begin
  359.                         line:=concat(line,'<',NumToStr(ver.stage),'>');
  360.                     end;
  361.                 end;
  362.                 if ver.nonRelRev <> 0 then begin
  363.                     line:=concat(line,NumToStr(ver.nonRelRev));
  364.                 end;
  365.             end;
  366.         end;
  367.         if manual_state = MS_Doing then begin
  368.             if not gotversion then begin
  369.                 CallManualResultError( -17, use_socks );
  370.             end else begin
  371.                 CallManualResult( noErr, new, use_socks, query_result, line, where );
  372.             end;
  373.         end else begin
  374.             if new & (newversion_callback <> nil) then begin
  375.                 newversion_callback(query_result, line, where);
  376.             end;
  377.         end;
  378.     end;
  379.     
  380.     procedure SIVCConnection.Closing;
  381.         var
  382.             size: longint;
  383.             date: longint;
  384.             junk: OSErr;
  385.     begin
  386.         HLock( query_result );
  387.         size := NetToMac( query_result^, GetHandleSize( query_result ) );
  388.         HUnlock( query_result );
  389.         SetHandleSize( query_result, size );
  390.         Close;
  391.         GetDateTime(date);
  392.         prefs.SetTagLong(PC_LastSIVC,date);
  393.         ProcessResult;
  394.         if (manual_state <> MS_Doing) then begin
  395.             prefs.SetTagLong(PC_LastCheckSIVCQuantum, GetThisQuantum);
  396.         end;
  397.         junk := WritePrefsData;
  398.     end;
  399.     
  400.     procedure ReleaseConnection;
  401.     begin
  402.         if ( conn_obj <> nil ) then begin
  403.             conn_obj.Destroy;
  404.         end;
  405.         if ( lookup_obj <> nil ) then begin
  406.             lookup_obj.Destroy;
  407.         end;
  408.         sivc_state := ST_None;
  409.     end;
  410.     
  411.     procedure StartQuery;
  412.         var
  413.             s: Str255;
  414.             use_socks: boolean;
  415.     begin
  416.         sivc_state := ST_Doing;
  417.         GetIndString(s,sivc_id,ord(SS_Server));
  418.         
  419.         s := 'tiny';
  420.         
  421.         ServerToHostPort(s,sivc_default_port,sivc_host,sivc_port);
  422.         GetSOCKSServer( sivc_host, s );
  423.         use_socks := s<>'';
  424.         if ( use_socks ) then begin
  425.             new(lookup_obj);
  426.             lookup_obj.FindAddress( sivc_host );
  427.         end else begin
  428.             new(conn_obj);
  429.             conn_obj.use_socks := false;
  430.             conn_obj.NewActiveConnection( 0, sivc_host, sivc_port );
  431.         end;
  432.     end;
  433.     
  434.     procedure IdleSIVC;
  435.         var
  436.             last_quantum: longint;
  437.     begin
  438.         if sivc_state = ST_None then begin
  439.             if (manual_state = MS_Want) | (TickCount > idle_til) then begin
  440.                 if (manual_state = MS_Want) then begin
  441.                     manual_state := MS_Doing;
  442.                     StartQuery;
  443.                 end else begin
  444.                     idle_til := TickCount + idle_til_period;
  445.                     if prefs.GetTagBoolean(PC_UseSIVC) then begin
  446.                         prefs.GetTagLong(PC_LastCheckSIVCQuantum,last_quantum);
  447.                         if (GetThisQuantum <> last_quantum) then begin
  448.                             StartQuery;
  449.                         end;
  450.                     end;
  451.                 end;
  452.             end
  453.         end;
  454.     end;
  455.     
  456.     function InitSIVC( var msg: integer ): OSStatus;
  457.         var
  458.             bndl:Handle;
  459.             date:longint;
  460.             junk: OSErr;
  461.     begin
  462. {$unused(msg)}
  463.         conn_obj := nil;
  464.         lookup_obj := nil;
  465.         manual_state := MS_None;
  466.         sivc_state := ST_None;
  467.         idle_til := TickCount;
  468.         GetVersion(vers);
  469.         app_creator := '????';
  470.         bndl := Get1Resource('BNDL', 128);
  471.         if (bndl <> nil) & (bndl^ <> nil) & (GetHandleSize(bndl) >= 4) then begin
  472.             BlockMoveData(bndl^, @app_creator[1], 4);
  473.         end;
  474.         GetDateTime(date);
  475.         SetDefaultLong(PC_FirstCheckSIVC,date);
  476.         SetDefaultLong(PC_LastCheckSIVCQuantum,-1234);
  477.         SetDefaultLong(PC_CheckSIVCPeriod,10080); { 1 week }
  478.         SetDefaultLong(PC_LastSIVC,bad_date);
  479.         SetDefaultLong(PC_SIVCUsers,-1);
  480.         first_ever_sivc := not prefs.ExistsTag(PC_UseSIVC);
  481.         junk := WritePrefsData;
  482.         InitSIVC := noErr;
  483.     end;
  484.     
  485.     procedure FinishSIVC;
  486.     begin
  487.         ReleaseConnection;
  488.         sivc_state := ST_Finished;
  489.     end;
  490.     
  491.     procedure ConfigureSIVC(newversion : SIVCNewVersionCallBack; getsocks:SIVCGetSOCKSServerCallBack);
  492.     begin
  493.         newversion_callback := newversion;
  494.         getsocks_callback := getsocks;
  495.         StartupSIVC;
  496.     end;
  497.     
  498.     procedure StartupSIVC;
  499.     begin        
  500.         StartupConnections;
  501.         SetStartup( InitSIVC, IdleSIVC, 60*10, FinishSIVC );
  502.     end;
  503.     
  504.     procedure ManualQuery(mqresult: SIVCManualQueryCallBack);
  505.     begin
  506.         if CanManualQuery then begin
  507.             mqresult_callback := mqresult;
  508.             manual_state := MS_Want;
  509.         end else begin
  510.             if (mqresult <> nil) then begin
  511.                 mqresult( aspServerBusy, false, false, nil, '', '' );
  512.             end;
  513.         end;
  514.     end;
  515.  
  516.     function CanManualQuery:Boolean;
  517.     begin
  518.         CanManualQuery := (manual_state = MS_None) & (sivc_state <> ST_Finished);
  519.     end;
  520.  
  521. end.
  522.     procedure StartupSIVC;
  523.     begin
  524.     end;
  525.     
  526.     procedure ConfigureSIVC(newversion : SIVCNewVersionCallBack; getsocks:SIVCGetSOCKSServerCallBack);
  527.     begin
  528.     end;    
  529.         
  530.     procedure ManualQuery(mqresult: SIVCManualQueryCallBack);
  531.     begin
  532.     end;
  533.     
  534.     function CanManualQuery:Boolean;
  535.     begin
  536.         CanManualQuery := false;
  537.     end;
  538.  
  539. end.
  540.  
  541.