p4ruby 2019.1.1873991 → 2021.1.2196401
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/LICENSE.txt +451 -20
- data/README.md +12 -875
- data/ext/P4/clientprogressruby.cpp +0 -1
- data/ext/P4/clientuserruby.cpp +254 -1
- data/ext/P4/clientuserruby.h +26 -1
- data/ext/P4/extconf.rb +66 -22
- data/ext/P4/p4.cpp +100 -9
- data/ext/P4/p4clientapi.cpp +75 -6
- data/ext/P4/p4clientapi.h +13 -2
- data/ext/P4/p4result.cpp +1 -0
- data/ext/P4/p4specdata.cpp +29 -0
- data/ext/P4/p4specdata.h +2 -0
- data/ext/P4/specmgr.cpp +43 -130
- data/lib/P4/version.rb +3 -3
- data/lib/P4.rb +16 -0
- metadata +9 -8
    
        data/ext/P4/clientuserruby.cpp
    CHANGED
    
    | @@ -38,6 +38,7 @@ | |
| 38 38 | 
             
            #include <ruby.h>
         | 
| 39 39 | 
             
            #include "undefdups.h"
         | 
| 40 40 | 
             
            #include <p4/clientapi.h>
         | 
| 41 | 
            +
            #include <p4/strtable.h>
         | 
| 41 42 | 
             
            #include <p4/clientprog.h>
         | 
| 42 43 | 
             
            #include <p4/spec.h>
         | 
| 43 44 | 
             
            #include <p4/diff.h>
         | 
| @@ -65,6 +66,19 @@ static const int CANCEL = 2; | |
| 65 66 | 
             
             * server, and converts the data to Ruby form for returning to the caller.
         | 
| 66 67 | 
             
             ******************************************************************************/
         | 
| 67 68 |  | 
| 69 | 
            +
            class SSOShim : public ClientSSO {
         | 
| 70 | 
            +
            public:
         | 
| 71 | 
            +
            	SSOShim(ClientUserRuby *ui) : ui(ui) {}
         | 
| 72 | 
            +
            	virtual ClientSSOStatus	Authorize( StrDict &vars,
         | 
| 73 | 
            +
            				           int maxLength,
         | 
| 74 | 
            +
            				           StrBuf &result )
         | 
| 75 | 
            +
            	{
         | 
| 76 | 
            +
            		return ui->Authorize(vars, maxLength, result);
         | 
| 77 | 
            +
            	}
         | 
| 78 | 
            +
            private:
         | 
| 79 | 
            +
            	ClientUserRuby *ui;
         | 
| 80 | 
            +
            } ;
         | 
| 81 | 
            +
             | 
| 68 82 | 
             
            ClientUserRuby::ClientUserRuby(SpecMgr *s) {
         | 
| 69 83 | 
             
            	specMgr = s;
         | 
| 70 84 | 
             
            	debug = 0;
         | 
| @@ -77,14 +91,22 @@ ClientUserRuby::ClientUserRuby(SpecMgr *s) { | |
| 77 91 | 
             
            	rubyExcept = 0;
         | 
| 78 92 | 
             
            	alive = 1;
         | 
| 79 93 | 
             
            	track = false;
         | 
| 94 | 
            +
                	SetSSOHandler( new SSOShim( this ) );
         | 
| 95 | 
            +
             | 
| 96 | 
            +
            	ssoEnabled = 0;
         | 
| 97 | 
            +
            	ssoResultSet = 0;
         | 
| 98 | 
            +
            	ssoResult = Qnil;
         | 
| 99 | 
            +
            	ssoHandler = Qnil;
         | 
| 80 100 |  | 
| 81 101 | 
             
            	ID idP4 = rb_intern("P4");
         | 
| 82 102 | 
             
            	ID idP4OH = rb_intern("OutputHandler");
         | 
| 83 103 | 
             
            	ID idP4Progress = rb_intern("Progress");
         | 
| 104 | 
            +
            	ID idP4SSO = rb_intern("SSOHandler");
         | 
| 84 105 |  | 
| 85 106 | 
             
            	VALUE cP4 = rb_const_get_at(rb_cObject, idP4);
         | 
| 86 107 | 
             
            	cOutputHandler = rb_const_get_at(cP4, idP4OH);
         | 
| 87 108 | 
             
            	cProgress = rb_const_get_at(cP4, idP4Progress );
         | 
| 109 | 
            +
            	cSSOHandler = rb_const_get_at(cP4, idP4SSO);
         | 
| 88 110 | 
             
            }
         | 
| 89 111 |  | 
| 90 112 | 
             
            void ClientUserRuby::Reset() {
         | 
| @@ -719,8 +741,239 @@ void ClientUserRuby::GCMark() { | |
| 719 741 | 
             
            	if (mergeResult != Qnil) rb_gc_mark( mergeResult);
         | 
| 720 742 | 
             
            	if (handler != Qnil) rb_gc_mark( handler);
         | 
| 721 743 | 
             
            	if (progress != Qnil) rb_gc_mark( progress );
         | 
| 722 | 
            -
            	rb_gc_mark(  | 
| 744 | 
            +
            	if (ssoResult != Qnil) rb_gc_mark( ssoResult );
         | 
| 745 | 
            +
            	if (ssoHandler != Qnil) rb_gc_mark( ssoHandler );
         | 
| 746 | 
            +
            	rb_gc_mark( cOutputHandler );
         | 
| 723 747 | 
             
            	rb_gc_mark( cProgress );
         | 
| 748 | 
            +
            	rb_gc_mark( cSSOHandler );
         | 
| 724 749 |  | 
| 725 750 | 
             
            	results.GCMark();
         | 
| 726 751 | 
             
            }
         | 
| 752 | 
            +
             | 
| 753 | 
            +
             | 
| 754 | 
            +
            /*
         | 
| 755 | 
            +
             * Set the Handler object. Double-check that it is either nil or
         | 
| 756 | 
            +
             * an instance of OutputHandler to avoid future problems
         | 
| 757 | 
            +
             */
         | 
| 758 | 
            +
             | 
| 759 | 
            +
            VALUE
         | 
| 760 | 
            +
            ClientUserRuby::SetRubySSOHandler(VALUE h) {
         | 
| 761 | 
            +
            	if (P4RDB_CALLS) fprintf(stderr, "[P4] SetSSOHandler()\n");
         | 
| 762 | 
            +
             | 
| 763 | 
            +
            	if (Qnil != h && Qfalse == rb_obj_is_kind_of(h, cSSOHandler)) {
         | 
| 764 | 
            +
            		rb_raise(eP4, "Handler needs to be an instance of P4::SSOHandler");
         | 
| 765 | 
            +
            		return Qfalse;
         | 
| 766 | 
            +
            	}
         | 
| 767 | 
            +
             | 
| 768 | 
            +
            	ssoHandler = h;
         | 
| 769 | 
            +
            	alive = 1; // ensure that we don't drop out after the next call
         | 
| 770 | 
            +
             | 
| 771 | 
            +
            	return Qtrue;
         | 
| 772 | 
            +
            }
         | 
| 773 | 
            +
             | 
| 774 | 
            +
             | 
| 775 | 
            +
            // returns true if output should be reported
         | 
| 776 | 
            +
            // false if the output is handled and should be ignored
         | 
| 777 | 
            +
            static VALUE CallMethodSSO(VALUE data) {
         | 
| 778 | 
            +
            	VALUE *args = reinterpret_cast<VALUE *>(data);
         | 
| 779 | 
            +
            	return rb_funcall(args[0], (ID) rb_intern("authorize"), 2, args[1], args[2]);
         | 
| 780 | 
            +
            }
         | 
| 781 | 
            +
             | 
| 782 | 
            +
            ClientSSOStatus
         | 
| 783 | 
            +
            ClientUserRuby::CallSSOMethod(VALUE vars, int maxLength, StrBuf &result) {
         | 
| 784 | 
            +
            	ClientSSOStatus answer = CSS_SKIP;
         | 
| 785 | 
            +
            	int excepted = 0;
         | 
| 786 | 
            +
            	result.Clear();
         | 
| 787 | 
            +
             | 
| 788 | 
            +
            	if (P4RDB_COMMANDS) fprintf(stderr, "[P4] CallSSOMethod\n");
         | 
| 789 | 
            +
             | 
| 790 | 
            +
            	// some wild hacks to satisfy the rb_protect method
         | 
| 791 | 
            +
             | 
| 792 | 
            +
            	VALUE args[3] = { ssoHandler, vars, INT2NUM( maxLength ) };
         | 
| 793 | 
            +
             | 
| 794 | 
            +
            	VALUE res = rb_protect(CallMethodSSO, (VALUE) args, &excepted);
         | 
| 795 | 
            +
             | 
| 796 | 
            +
            	if (excepted) { // exception thrown
         | 
| 797 | 
            +
            		alive = 0;
         | 
| 798 | 
            +
            		rb_jump_tag(excepted);
         | 
| 799 | 
            +
            	} else if( FIXNUM_P( res ) ) {
         | 
| 800 | 
            +
            		int a = NUM2INT(res);
         | 
| 801 | 
            +
            		if (P4RDB_COMMANDS)
         | 
| 802 | 
            +
            			fprintf(stderr, "[P4] CallSSOMethod returned %d\n", a);
         | 
| 803 | 
            +
             | 
| 804 | 
            +
            		if( a < CSS_PASS || a > CSS_SKIP )
         | 
| 805 | 
            +
            			rb_raise(eP4, "P4::SSOHandler::authorize returned out of range response");
         | 
| 806 | 
            +
            		answer = (ClientSSOStatus) a;
         | 
| 807 | 
            +
            	} else if( Qtrue == rb_obj_is_kind_of(res, rb_cArray) ) {
         | 
| 808 | 
            +
            		VALUE resval1 = rb_ary_shift(res);
         | 
| 809 | 
            +
            		Check_Type( resval1, T_FIXNUM );
         | 
| 810 | 
            +
            		int a = NUM2INT(resval1);
         | 
| 811 | 
            +
            		if( a < CSS_PASS || a > CSS_SKIP )
         | 
| 812 | 
            +
            			rb_raise(eP4, "P4::SSOHandler::authorize returned out of range response");
         | 
| 813 | 
            +
            		answer = (ClientSSOStatus) a;
         | 
| 814 | 
            +
             | 
| 815 | 
            +
            		VALUE resval2 = rb_ary_shift(res);
         | 
| 816 | 
            +
            		if( resval2 != Qnil )
         | 
| 817 | 
            +
            		{
         | 
| 818 | 
            +
            			Check_Type( resval2, T_STRING );
         | 
| 819 | 
            +
            			result.Set(StringValuePtr(resval2));
         | 
| 820 | 
            +
            			if (P4RDB_COMMANDS)
         | 
| 821 | 
            +
            				fprintf(stderr, "[P4] CallSSOMethod returned %d, %s\n", a, result.Text());
         | 
| 822 | 
            +
            		}
         | 
| 823 | 
            +
             | 
| 824 | 
            +
            	} else {
         | 
| 825 | 
            +
            		Check_Type( res, T_STRING );
         | 
| 826 | 
            +
            		answer = CSS_PASS;
         | 
| 827 | 
            +
             | 
| 828 | 
            +
            		result.Set(StringValuePtr(res));
         | 
| 829 | 
            +
            		if (P4RDB_COMMANDS)
         | 
| 830 | 
            +
            			fprintf(stderr, "[P4] CallSSOMethod returned %s\n", result.Text());
         | 
| 831 | 
            +
             | 
| 832 | 
            +
            	}
         | 
| 833 | 
            +
             | 
| 834 | 
            +
            	return answer;
         | 
| 835 | 
            +
            }
         | 
| 836 | 
            +
             | 
| 837 | 
            +
            ClientSSOStatus
         | 
| 838 | 
            +
            ClientUserRuby::Authorize( StrDict &vars, int maxLength, StrBuf &strbuf )
         | 
| 839 | 
            +
            {
         | 
| 840 | 
            +
            	ssoVars.Clear();
         | 
| 841 | 
            +
             | 
| 842 | 
            +
            	if( ssoHandler != Qnil )
         | 
| 843 | 
            +
            	{
         | 
| 844 | 
            +
            		ClientSSOStatus res = CallSSOMethod( specMgr->StrDictToHash(&vars), maxLength, strbuf );
         | 
| 845 | 
            +
            		if( res != CSS_SKIP )
         | 
| 846 | 
            +
            			return res;
         | 
| 847 | 
            +
            		if (P4RDB_COMMANDS)
         | 
| 848 | 
            +
            			fprintf(stderr, "[P4] Authorize skipped result from SSO Handler\n" );
         | 
| 849 | 
            +
            	}
         | 
| 850 | 
            +
             | 
| 851 | 
            +
            	if( !ssoEnabled )
         | 
| 852 | 
            +
            		return CSS_SKIP;
         | 
| 853 | 
            +
             | 
| 854 | 
            +
            	if( ssoEnabled < 0 )
         | 
| 855 | 
            +
            		return CSS_UNSET;
         | 
| 856 | 
            +
             | 
| 857 | 
            +
            	if( ssoResultSet )
         | 
| 858 | 
            +
            	{
         | 
| 859 | 
            +
            		strbuf.Clear();
         | 
| 860 | 
            +
            			VALUE resval = ssoResult;
         | 
| 861 | 
            +
             | 
| 862 | 
            +
            		//if( P4RDB_CALLS )
         | 
| 863 | 
            +
            		//    std::cerr << "[P4] ClientSSO::Authorize(). Using supplied input"
         | 
| 864 | 
            +
            		//              << std::endl;
         | 
| 865 | 
            +
             | 
| 866 | 
            +
            		if (Qtrue == rb_obj_is_kind_of(ssoResult, rb_cArray)) {
         | 
| 867 | 
            +
            			resval = rb_ary_shift(ssoResult);
         | 
| 868 | 
            +
            		}
         | 
| 869 | 
            +
            	
         | 
| 870 | 
            +
            		if( resval != Qnil ) {
         | 
| 871 | 
            +
            			// Convert whatever's left into a string
         | 
| 872 | 
            +
            			ID to_s = rb_intern("to_s");
         | 
| 873 | 
            +
            			VALUE str = rb_funcall(resval, to_s, 0);
         | 
| 874 | 
            +
            			strbuf.Set(StringValuePtr(str));
         | 
| 875 | 
            +
            		}
         | 
| 876 | 
            +
             | 
| 877 | 
            +
            		return ssoResultSet == 2 ? CSS_FAIL
         | 
| 878 | 
            +
            				: CSS_PASS;
         | 
| 879 | 
            +
            	}
         | 
| 880 | 
            +
             | 
| 881 | 
            +
            	ssoVars.CopyVars( vars );
         | 
| 882 | 
            +
            	return CSS_EXIT;
         | 
| 883 | 
            +
            }
         | 
| 884 | 
            +
             | 
| 885 | 
            +
            VALUE
         | 
| 886 | 
            +
            ClientUserRuby::EnableSSO( VALUE e )
         | 
| 887 | 
            +
            {
         | 
| 888 | 
            +
            	if( e == Qnil )
         | 
| 889 | 
            +
            	{
         | 
| 890 | 
            +
            		ssoEnabled = 0;
         | 
| 891 | 
            +
            		return Qtrue;
         | 
| 892 | 
            +
            	}
         | 
| 893 | 
            +
             | 
| 894 | 
            +
            	if( e == Qtrue )
         | 
| 895 | 
            +
            	{
         | 
| 896 | 
            +
            		ssoEnabled = 1;
         | 
| 897 | 
            +
            		return Qtrue;
         | 
| 898 | 
            +
            	}
         | 
| 899 | 
            +
             | 
| 900 | 
            +
            	if( e == Qfalse )
         | 
| 901 | 
            +
            	{
         | 
| 902 | 
            +
            		ssoEnabled = -1;
         | 
| 903 | 
            +
            		return Qtrue;
         | 
| 904 | 
            +
            	}
         | 
| 905 | 
            +
             | 
| 906 | 
            +
            	return Qfalse;
         | 
| 907 | 
            +
            }
         | 
| 908 | 
            +
             | 
| 909 | 
            +
            VALUE
         | 
| 910 | 
            +
            ClientUserRuby::SSOEnabled()
         | 
| 911 | 
            +
            {
         | 
| 912 | 
            +
            	if( ssoEnabled == 1 )
         | 
| 913 | 
            +
            	{
         | 
| 914 | 
            +
            		return Qtrue;
         | 
| 915 | 
            +
            	}
         | 
| 916 | 
            +
            	else if( ssoEnabled == -1 )
         | 
| 917 | 
            +
            	{
         | 
| 918 | 
            +
            		return Qfalse;
         | 
| 919 | 
            +
            	}
         | 
| 920 | 
            +
            	else
         | 
| 921 | 
            +
            	{
         | 
| 922 | 
            +
            		return Qnil;
         | 
| 923 | 
            +
            	}
         | 
| 924 | 
            +
            }
         | 
| 925 | 
            +
             | 
| 926 | 
            +
            VALUE
         | 
| 927 | 
            +
            ClientUserRuby::SetSSOPassResult( VALUE i )
         | 
| 928 | 
            +
            {
         | 
| 929 | 
            +
            	ssoResultSet = 1;
         | 
| 930 | 
            +
            	return SetSSOResult( i );
         | 
| 931 | 
            +
            }
         | 
| 932 | 
            +
             | 
| 933 | 
            +
            VALUE
         | 
| 934 | 
            +
            ClientUserRuby::GetSSOPassResult()
         | 
| 935 | 
            +
            {
         | 
| 936 | 
            +
            	if( ssoResultSet == 1 )
         | 
| 937 | 
            +
            	{
         | 
| 938 | 
            +
            		return ssoResult;
         | 
| 939 | 
            +
            	}
         | 
| 940 | 
            +
            	else
         | 
| 941 | 
            +
            	{
         | 
| 942 | 
            +
            		return Qnil;
         | 
| 943 | 
            +
            	}
         | 
| 944 | 
            +
            }
         | 
| 945 | 
            +
             | 
| 946 | 
            +
            VALUE
         | 
| 947 | 
            +
            ClientUserRuby::SetSSOFailResult( VALUE i )
         | 
| 948 | 
            +
            {
         | 
| 949 | 
            +
            	ssoResultSet = 2;
         | 
| 950 | 
            +
            	return SetSSOResult( i );
         | 
| 951 | 
            +
            }
         | 
| 952 | 
            +
             | 
| 953 | 
            +
            VALUE
         | 
| 954 | 
            +
            ClientUserRuby::GetSSOFailResult()
         | 
| 955 | 
            +
            {
         | 
| 956 | 
            +
            	if( ssoResultSet == 2 )
         | 
| 957 | 
            +
            	{
         | 
| 958 | 
            +
            		return ssoResult;
         | 
| 959 | 
            +
            	}
         | 
| 960 | 
            +
            	else
         | 
| 961 | 
            +
            	{
         | 
| 962 | 
            +
            		return Qnil;
         | 
| 963 | 
            +
            	}
         | 
| 964 | 
            +
            }
         | 
| 965 | 
            +
             | 
| 966 | 
            +
            VALUE
         | 
| 967 | 
            +
            ClientUserRuby::SetSSOResult( VALUE i )
         | 
| 968 | 
            +
            {
         | 
| 969 | 
            +
            	if (P4RDB_CALLS) fprintf(stderr, "[P4] P4ClientSSO::SetResult()\n");
         | 
| 970 | 
            +
             
         | 
| 971 | 
            +
            	ssoResult = i;
         | 
| 972 | 
            +
            	return Qtrue;
         | 
| 973 | 
            +
            }
         | 
| 974 | 
            +
             | 
| 975 | 
            +
            VALUE
         | 
| 976 | 
            +
            ClientUserRuby::GetSSOVars()
         | 
| 977 | 
            +
            {
         | 
| 978 | 
            +
                	return specMgr->StrDictToHash( &ssoVars );
         | 
| 979 | 
            +
            }
         | 
    
        data/ext/P4/clientuserruby.h
    CHANGED
    
    | @@ -42,7 +42,7 @@ | |
| 42 42 | 
             
            class SpecMgr;
         | 
| 43 43 | 
             
            class ClientProgress;
         | 
| 44 44 |  | 
| 45 | 
            -
            class ClientUserRuby: public ClientUser, public KeepAlive {
         | 
| 45 | 
            +
            class ClientUserRuby: public ClientUser, public ClientSSO, public KeepAlive {
         | 
| 46 46 | 
             
            public:
         | 
| 47 47 | 
             
            	ClientUserRuby(SpecMgr *s);
         | 
| 48 48 |  | 
| @@ -101,6 +101,21 @@ public: | |
| 101 101 | 
             
            		return progress;
         | 
| 102 102 | 
             
            	}
         | 
| 103 103 |  | 
| 104 | 
            +
            	// SSO handler support
         | 
| 105 | 
            +
             | 
| 106 | 
            +
            	virtual ClientSSOStatus Authorize( StrDict &vars, int maxLength, StrBuf &result );
         | 
| 107 | 
            +
            	VALUE EnableSSO( VALUE e );
         | 
| 108 | 
            +
            	VALUE SSOEnabled();
         | 
| 109 | 
            +
            	VALUE SetSSOPassResult( VALUE i );
         | 
| 110 | 
            +
            	VALUE GetSSOPassResult();
         | 
| 111 | 
            +
            	VALUE SetSSOFailResult( VALUE i );
         | 
| 112 | 
            +
            	VALUE GetSSOFailResult();
         | 
| 113 | 
            +
            	VALUE GetSSOVars();
         | 
| 114 | 
            +
            	VALUE SetRubySSOHandler( VALUE handler );
         | 
| 115 | 
            +
            	VALUE GetRubySSOHandler() {
         | 
| 116 | 
            +
            		return ssoHandler;
         | 
| 117 | 
            +
            	}
         | 
| 118 | 
            +
             | 
| 104 119 | 
             
            	// override from KeepAlive
         | 
| 105 120 | 
             
            	virtual int IsAlive() {
         | 
| 106 121 | 
             
            		return alive;
         | 
| @@ -112,6 +127,8 @@ private: | |
| 112 127 | 
             
            	void ProcessOutput(const char * method, VALUE data);
         | 
| 113 128 | 
             
            	void ProcessMessage(Error * e);
         | 
| 114 129 | 
             
            	bool CallOutputMethod(const char * method, VALUE data);
         | 
| 130 | 
            +
            	VALUE SetSSOResult( VALUE i );
         | 
| 131 | 
            +
            	ClientSSOStatus CallSSOMethod(VALUE vars, int maxLength, StrBuf &result);
         | 
| 115 132 |  | 
| 116 133 | 
             
            private:
         | 
| 117 134 | 
             
            	StrBuf cmd;
         | 
| @@ -124,10 +141,18 @@ private: | |
| 124 141 | 
             
            	VALUE cOutputHandler;
         | 
| 125 142 | 
             
            	VALUE progress;
         | 
| 126 143 | 
             
            	VALUE cProgress;
         | 
| 144 | 
            +
            	VALUE cSSOHandler;
         | 
| 127 145 | 
             
            	int debug;
         | 
| 128 146 | 
             
            	int apiLevel;
         | 
| 129 147 | 
             
            	int alive;
         | 
| 130 148 | 
             
            	int rubyExcept;
         | 
| 131 149 | 
             
            	bool track;
         | 
| 150 | 
            +
            	
         | 
| 151 | 
            +
            	// SSO handler support
         | 
| 152 | 
            +
            	int         ssoEnabled;
         | 
| 153 | 
            +
            	int         ssoResultSet;
         | 
| 154 | 
            +
            	StrBufDict  ssoVars;
         | 
| 155 | 
            +
            	VALUE       ssoResult;
         | 
| 156 | 
            +
            	VALUE 	    ssoHandler;
         | 
| 132 157 | 
             
            };
         | 
| 133 158 |  | 
    
        data/ext/P4/extconf.rb
    CHANGED
    
    | @@ -6,10 +6,19 @@ require 'mkmf' | |
| 6 6 | 
             
            require 'net/ftp'
         | 
| 7 7 | 
             
            require 'P4/version'
         | 
| 8 8 | 
             
            require 'rbconfig'
         | 
| 9 | 
            +
            require 'openssl'
         | 
| 9 10 |  | 
| 10 11 | 
             
            # Set this to the main version directory we look up in ftp.perforce.com for the P4API
         | 
| 11 12 | 
             
            # This is ignored if you specify the version on the command line.
         | 
| 12 | 
            -
             | 
| 13 | 
            +
            # Changed the hardcoded string so that the version is now derived from version.rb file
         | 
| 14 | 
            +
            #P4API_VERSION_DIR = 'r19.1'
         | 
| 15 | 
            +
            def p4api_version_dir
         | 
| 16 | 
            +
                    ver=P4::Version.split(".")
         | 
| 17 | 
            +
                    p4_major = ver[0].chars.last(2).join
         | 
| 18 | 
            +
                    p4_minor = ver[1]
         | 
| 19 | 
            +
                    dir = "r" + p4_major + "." + p4_minor
         | 
| 20 | 
            +
            end
         | 
| 21 | 
            +
             | 
| 13 22 |  | 
| 14 23 | 
             
            #==============================================================================
         | 
| 15 24 | 
             
            # Provide platform variables in P4-specific format
         | 
| @@ -102,6 +111,15 @@ def calculate_p4osver | |
| 102 111 | 
             
              return ver
         | 
| 103 112 | 
             
            end
         | 
| 104 113 |  | 
| 114 | 
            +
            def gcc
         | 
| 115 | 
            +
              @gcc ||= calculate_gcc
         | 
| 116 | 
            +
            end
         | 
| 117 | 
            +
             | 
| 118 | 
            +
            def calculate_gcc
         | 
| 119 | 
            +
              gcc = RbConfig::CONFIG["GCC"]
         | 
| 120 | 
            +
              return gcc
         | 
| 121 | 
            +
            end
         | 
| 122 | 
            +
             | 
| 105 123 | 
             
            def uname_platform
         | 
| 106 124 | 
             
              @uname_platform ||= calculate_uname_platform
         | 
| 107 125 | 
             
            end
         | 
| @@ -155,6 +173,13 @@ def set_platform_opts | |
| 155 173 | 
             
              end
         | 
| 156 174 | 
             
            end
         | 
| 157 175 |  | 
| 176 | 
            +
            def set_platform_cxxflags
         | 
| 177 | 
            +
              if (p4osname == 'LINUX') && (gcc == 'yes')
         | 
| 178 | 
            +
                $CXXFLAGS += " -std=c++11 "
         | 
| 179 | 
            +
              end
         | 
| 180 | 
            +
            end
         | 
| 181 | 
            +
             | 
| 182 | 
            +
             | 
| 158 183 | 
             
            def set_platform_cppflags
         | 
| 159 184 | 
             
              $CPPFLAGS += "-DOS_#{p4osname} "
         | 
| 160 185 | 
             
              $CPPFLAGS += "-DOS_#{p4osname}#{p4osver} "
         | 
| @@ -400,6 +425,8 @@ def p4_cpu(os) | |
| 400 425 | 
             
                when :darwin, :linux
         | 
| 401 426 | 
             
                  if cpu =~ /i686/
         | 
| 402 427 | 
             
                    'x86'
         | 
| 428 | 
            +
                  elsif cpu =~ /universal/
         | 
| 429 | 
            +
                    'x86_64'
         | 
| 403 430 | 
             
                  else
         | 
| 404 431 | 
             
                    cpu
         | 
| 405 432 | 
             
                  end
         | 
| @@ -417,23 +444,19 @@ end | |
| 417 444 | 
             
            # directory name where we can download files from.
         | 
| 418 445 | 
             
            def p4_platform_label
         | 
| 419 446 | 
             
              case RbConfig::CONFIG["target_os"].downcase
         | 
| 420 | 
            -
                when /nt|mswin|mingw/
         | 
| 447 | 
            +
                when /nt|mswin|mingw|cygwin|msys/
         | 
| 421 448 | 
             
                  # Ruby on windows is only MinGW via Rubyinstaller.org, though this may
         | 
| 422 449 | 
             
                  # not work on all rubies.
         | 
| 423 | 
            -
                   | 
| 424 | 
            -
             | 
| 425 | 
            -
             | 
| 426 | 
            -
                   | 
| 427 | 
            -
             | 
| 428 | 
            -
                  end
         | 
| 429 | 
            -
                when /darwin/
         | 
| 450 | 
            +
                  # There are too many permutations of Windows p4api, to automate.
         | 
| 451 | 
            +
                  raise 'Automatic fetching of p4api from perforce FTP is not supported on Windows'
         | 
| 452 | 
            +
                when /darwin19|darwin[2-9][0-9]/
         | 
| 453 | 
            +
                  "macosx1015#{p4_cpu(:darwin)}"
         | 
| 454 | 
            +
                when /darwin/      
         | 
| 430 455 | 
             
                  "darwin90#{p4_cpu(:darwin)}"
         | 
| 431 456 | 
             
                when /solaris/
         | 
| 432 457 | 
             
                  "solaris10#{p4_cpu(:solaris)}"
         | 
| 433 458 | 
             
                when /linux/
         | 
| 434 | 
            -
                  "linux26#{p4_cpu(:linux)}"
         | 
| 435 | 
            -
                when /cygwin/
         | 
| 436 | 
            -
                  raise 'cygwin is not supported for the --download-p4api option'
         | 
| 459 | 
            +
                  "linux26#{p4_cpu(:linux)}"    
         | 
| 437 460 | 
             
              end
         | 
| 438 461 | 
             
            end
         | 
| 439 462 |  | 
| @@ -446,13 +469,36 @@ def ftp_download_dir(version) | |
| 446 469 | 
             
            end
         | 
| 447 470 |  | 
| 448 471 | 
             
            def filename
         | 
| 472 | 
            +
              openssl_number = OpenSSL::OPENSSL_VERSION.split(' ')[1].to_s
         | 
| 473 | 
            +
              openssl_number = openssl_number.slice(0, (openssl_number.rindex('.')))
         | 
| 474 | 
            +
             | 
| 449 475 | 
             
              if RbConfig::CONFIG['target_os'].downcase =~ /nt|mswin|mingw/
         | 
| 450 | 
            -
                'p4api.zip'
         | 
| 476 | 
            +
                filename = 'p4api.zip'
         | 
| 477 | 
            +
                if !openssl_number.to_s.empty?
         | 
| 478 | 
            +
                    case openssl_number.to_s
         | 
| 479 | 
            +
                        when /1.1/
         | 
| 480 | 
            +
                            filename = 'p4api-openssl1.1.1.zip'
         | 
| 481 | 
            +
                        when /1.0/
         | 
| 482 | 
            +
                            filename = 'p4api-openssl1.0.2.zip'
         | 
| 483 | 
            +
                         end
         | 
| 484 | 
            +
                end
         | 
| 485 | 
            +
              elsif RbConfig::CONFIG['target_os'].downcase =~ /darwin19|darwin[2-9][0-9]/
         | 
| 486 | 
            +
                filename = 'p4api-openssl1.1.1.tgz'
         | 
| 451 487 | 
             
              else
         | 
| 452 | 
            -
                'p4api.tgz'
         | 
| 488 | 
            +
                filename = 'p4api.tgz'
         | 
| 489 | 
            +
                if !openssl_number.to_s.empty?
         | 
| 490 | 
            +
                    case openssl_number.to_s
         | 
| 491 | 
            +
                        when /1.1/
         | 
| 492 | 
            +
                            filename = 'p4api-glibc2.3-openssl1.1.1.tgz'
         | 
| 493 | 
            +
                        when /1.0/
         | 
| 494 | 
            +
                            filename = 'p4api-glibc2.3-openssl1.0.2.tgz'
         | 
| 495 | 
            +
                    end
         | 
| 496 | 
            +
                end
         | 
| 453 497 | 
             
              end
         | 
| 498 | 
            +
              return filename
         | 
| 454 499 | 
             
            end
         | 
| 455 500 |  | 
| 501 | 
            +
             | 
| 456 502 | 
             
            def remote_files_matching(ftp, dir, regex)
         | 
| 457 503 | 
             
              ftp.ls(dir.to_s).map { |entry|
         | 
| 458 504 | 
             
                if match = entry.match(regex)
         | 
| @@ -500,9 +546,8 @@ def download_api_via_ftp | |
| 500 546 | 
             
              # At one point, we allowed the gem build to just find the most recent p4api build.
         | 
| 501 547 | 
             
              # P4Ruby probably shouldn't do that by default.
         | 
| 502 548 | 
             
              #version_dir = find_latest_version_dir(ftp)
         | 
| 503 | 
            -
              version_dir = P4API_VERSION_DIR
         | 
| 504 549 |  | 
| 505 | 
            -
              dir = ftp_download_dir( | 
| 550 | 
            +
              dir = ftp_download_dir(p4api_version_dir)
         | 
| 506 551 | 
             
              ftp.chdir(dir)
         | 
| 507 552 |  | 
| 508 553 | 
             
              puts "downloading #{filename} from #{dir} on ftp.perforce.com"
         | 
| @@ -537,9 +582,11 @@ set_platform_opts | |
| 537 582 | 
             
            # based solely on platform detection.
         | 
| 538 583 | 
             
            set_platform_cppflags
         | 
| 539 584 | 
             
            set_platform_cflags
         | 
| 585 | 
            +
            set_platform_cxxflags
         | 
| 540 586 |  | 
| 541 587 | 
             
            puts "$CPPFLAGS #{$CPPFLAGS}"
         | 
| 542 588 | 
             
            puts "$CFLAGS #{$CFLAGS}"
         | 
| 589 | 
            +
            puts "$CXXFLAGS #{$CXXFLAGS}"
         | 
| 543 590 |  | 
| 544 591 | 
             
            # Setup additional system library definitions based on platform type before
         | 
| 545 592 | 
             
            # we setup other libraries, in order to preserve linking order
         | 
| @@ -556,14 +603,11 @@ resolve_ssl_dirs | |
| 556 603 | 
             
            if RbConfig::CONFIG['target_os'].downcase =~ /mingw/
         | 
| 557 604 | 
             
              have_library('gdi32') or raise
         | 
| 558 605 | 
             
              have_library('ole32') or raise
         | 
| 606 | 
            +
              have_library('crypt32') or raise
         | 
| 559 607 | 
             
            end
         | 
| 560 608 |  | 
| 561 | 
            -
             | 
| 562 | 
            -
             | 
| 563 | 
            -
            unless do_ssl
         | 
| 564 | 
            -
              have_library('p4sslstub') or raise
         | 
| 565 | 
            -
            end
         | 
| 566 | 
            -
             | 
| 609 | 
            +
            have_library('crypto') or raise
         | 
| 610 | 
            +
            have_library('ssl') or raise
         | 
| 567 611 | 
             
            have_library('supp') or raise
         | 
| 568 612 | 
             
            have_library('p4script_sqlite') or raise
         | 
| 569 613 | 
             
            have_library('p4script_curl') or raise
         | 
    
        data/ext/P4/p4.cpp
    CHANGED
    
    | @@ -314,6 +314,25 @@ static VALUE p4_set_enviro_file( VALUE self, VALUE rbstr ) | |
| 314 314 | 
             
                return Qtrue;
         | 
| 315 315 | 
             
            }
         | 
| 316 316 |  | 
| 317 | 
            +
            static VALUE p4_get_evar( VALUE self, VALUE var )
         | 
| 318 | 
            +
            {
         | 
| 319 | 
            +
                P4ClientApi	*p4;
         | 
| 320 | 
            +
                const StrPtr *val;
         | 
| 321 | 
            +
                Data_Get_Struct( self, P4ClientApi, p4 );
         | 
| 322 | 
            +
                val = p4->GetEVar( StringValuePtr( var ) );
         | 
| 323 | 
            +
                if( !val ) return Qnil;
         | 
| 324 | 
            +
             | 
| 325 | 
            +
                return P4Utils::ruby_string( val->Text() );
         | 
| 326 | 
            +
            }
         | 
| 327 | 
            +
             | 
| 328 | 
            +
            static VALUE p4_set_evar( VALUE self, VALUE var, VALUE val )
         | 
| 329 | 
            +
            {
         | 
| 330 | 
            +
                P4ClientApi *p4;
         | 
| 331 | 
            +
                Data_Get_Struct( self, P4ClientApi, p4 );
         | 
| 332 | 
            +
                p4->SetEVar( StringValuePtr( var ), StringValuePtr( val ) );
         | 
| 333 | 
            +
                return Qtrue;
         | 
| 334 | 
            +
            }
         | 
| 335 | 
            +
             | 
| 317 336 | 
             
            static VALUE p4_get_host( VALUE self )
         | 
| 318 337 | 
             
            {
         | 
| 319 338 | 
             
                P4ClientApi	*p4;
         | 
| @@ -642,7 +661,7 @@ static VALUE p4_run( VALUE self, VALUE args ) | |
| 642 661 |  | 
| 643 662 | 
             
                // Allocate storage on the stack so it's automatically reclaimed
         | 
| 644 663 | 
             
                // when we exit.
         | 
| 645 | 
            -
                char **p4args =  | 
| 664 | 
            +
                char **p4args = RB_ALLOC_N( char *, argc + 1 );
         | 
| 646 665 |  | 
| 647 666 | 
             
                // Copy the args across
         | 
| 648 667 | 
             
                for ( i = 0; i < argc; i++ )
         | 
| @@ -679,13 +698,6 @@ static VALUE p4_get_messages( VALUE self ) | |
| 679 698 | 
             
                return p4->GetMessages();
         | 
| 680 699 | 
             
            }
         | 
| 681 700 |  | 
| 682 | 
            -
            static VALUE p4_reset( VALUE self )
         | 
| 683 | 
            -
            {
         | 
| 684 | 
            -
                P4ClientApi *p4;
         | 
| 685 | 
            -
                Data_Get_Struct( self, P4ClientApi, p4 );
         | 
| 686 | 
            -
                return p4->Reset();
         | 
| 687 | 
            -
            }
         | 
| 688 | 
            -
             | 
| 689 701 | 
             
            static VALUE p4_get_warnings( VALUE self )
         | 
| 690 702 | 
             
            {
         | 
| 691 703 | 
             
                P4ClientApi	*p4;
         | 
| @@ -815,6 +827,72 @@ static VALUE p4_set_progress( VALUE self, VALUE progress ) | |
| 815 827 | 
             
                return p4->SetProgress( progress );
         | 
| 816 828 | 
             
            }
         | 
| 817 829 |  | 
| 830 | 
            +
            /*******************************************************************************
         | 
| 831 | 
            +
             * SSO handler support
         | 
| 832 | 
            +
             ******************************************************************************/
         | 
| 833 | 
            +
            static VALUE p4_get_enabled_sso( VALUE self )
         | 
| 834 | 
            +
            {
         | 
| 835 | 
            +
                P4ClientApi	*p4;
         | 
| 836 | 
            +
                Data_Get_Struct( self, P4ClientApi, p4 );
         | 
| 837 | 
            +
                return p4->GetEnableSSO();
         | 
| 838 | 
            +
            }
         | 
| 839 | 
            +
             | 
| 840 | 
            +
            static VALUE p4_set_enable_sso( VALUE self, VALUE enable )
         | 
| 841 | 
            +
            {
         | 
| 842 | 
            +
                P4ClientApi	*p4;
         | 
| 843 | 
            +
                Data_Get_Struct( self, P4ClientApi, p4 );
         | 
| 844 | 
            +
                return p4->SetEnableSSO( enable );
         | 
| 845 | 
            +
            }
         | 
| 846 | 
            +
             | 
| 847 | 
            +
            static VALUE p4_get_sso_vars( VALUE self )
         | 
| 848 | 
            +
            {
         | 
| 849 | 
            +
                P4ClientApi	*p4;
         | 
| 850 | 
            +
                Data_Get_Struct( self, P4ClientApi, p4 );
         | 
| 851 | 
            +
                return p4->GetSSOVars();
         | 
| 852 | 
            +
            }
         | 
| 853 | 
            +
             | 
| 854 | 
            +
            static VALUE p4_get_sso_passresult( VALUE self )
         | 
| 855 | 
            +
            {
         | 
| 856 | 
            +
                P4ClientApi	*p4;
         | 
| 857 | 
            +
                Data_Get_Struct( self, P4ClientApi, p4 );
         | 
| 858 | 
            +
                return p4->GetSSOPassResult();
         | 
| 859 | 
            +
            }
         | 
| 860 | 
            +
             | 
| 861 | 
            +
            static VALUE p4_set_sso_passresult( VALUE self, VALUE result )
         | 
| 862 | 
            +
            {
         | 
| 863 | 
            +
                P4ClientApi	*p4;
         | 
| 864 | 
            +
                Data_Get_Struct( self, P4ClientApi, p4 );
         | 
| 865 | 
            +
                return p4->SetSSOPassResult( result );
         | 
| 866 | 
            +
            }
         | 
| 867 | 
            +
             | 
| 868 | 
            +
            static VALUE p4_get_sso_failresult( VALUE self )
         | 
| 869 | 
            +
            {
         | 
| 870 | 
            +
                P4ClientApi	*p4;
         | 
| 871 | 
            +
                Data_Get_Struct( self, P4ClientApi, p4 );
         | 
| 872 | 
            +
                return p4->GetSSOFailResult();
         | 
| 873 | 
            +
            }
         | 
| 874 | 
            +
             | 
| 875 | 
            +
            static VALUE p4_set_sso_failresult( VALUE self, VALUE result )
         | 
| 876 | 
            +
            {
         | 
| 877 | 
            +
                P4ClientApi	*p4;
         | 
| 878 | 
            +
                Data_Get_Struct( self, P4ClientApi, p4 );
         | 
| 879 | 
            +
                return p4->SetSSOFailResult( result );
         | 
| 880 | 
            +
            }
         | 
| 881 | 
            +
            static VALUE p4_get_ssohandler( VALUE self )
         | 
| 882 | 
            +
            {
         | 
| 883 | 
            +
                P4ClientApi	*p4;
         | 
| 884 | 
            +
                Data_Get_Struct( self, P4ClientApi, p4 );
         | 
| 885 | 
            +
                return p4->GetSSOHandler();
         | 
| 886 | 
            +
            }
         | 
| 887 | 
            +
             | 
| 888 | 
            +
            static VALUE p4_set_ssohandler( VALUE self, VALUE handler )
         | 
| 889 | 
            +
            {
         | 
| 890 | 
            +
                P4ClientApi	*p4;
         | 
| 891 | 
            +
                Data_Get_Struct( self, P4ClientApi, p4 );
         | 
| 892 | 
            +
                p4->SetSSOHandler( handler );
         | 
| 893 | 
            +
                return Qtrue;
         | 
| 894 | 
            +
            }
         | 
| 895 | 
            +
             | 
| 818 896 | 
             
            /*******************************************************************************
         | 
| 819 897 | 
             
             * P4::MergeData methods. Construction/destruction defined elsewhere
         | 
| 820 898 | 
             
             ******************************************************************************/
         | 
| @@ -1269,6 +1347,8 @@ void	Init_P4() | |
| 1269 1347 | 
             
                rb_define_method( cP4, "set_env", 	RUBY_METHOD_FUNC(p4_set_env)     , 2 );
         | 
| 1270 1348 | 
             
                rb_define_method( cP4, "enviro_file", RUBY_METHOD_FUNC(p4_get_enviro_file), 0);
         | 
| 1271 1349 | 
             
                rb_define_method( cP4, "enviro_file=", RUBY_METHOD_FUNC(p4_set_enviro_file), 1);
         | 
| 1350 | 
            +
                rb_define_method( cP4, "evar", 	RUBY_METHOD_FUNC(p4_get_evar)     , 1 );
         | 
| 1351 | 
            +
                rb_define_method( cP4, "set_evar", 	RUBY_METHOD_FUNC(p4_set_evar)     , 2 );
         | 
| 1272 1352 | 
             
                rb_define_method( cP4, "host", 	RUBY_METHOD_FUNC(p4_get_host)    , 0 );
         | 
| 1273 1353 | 
             
                rb_define_method( cP4, "host=", 	RUBY_METHOD_FUNC(p4_set_host)    , 1 );
         | 
| 1274 1354 | 
             
                rb_define_method( cP4, "ignore_file",RUBY_METHOD_FUNC(p4_get_ignore) , 0 );
         | 
| @@ -1305,7 +1385,6 @@ void	Init_P4() | |
| 1305 1385 | 
             
                rb_define_method( cP4, "connect", 	RUBY_METHOD_FUNC(p4_connect)     , 0 );
         | 
| 1306 1386 | 
             
                rb_define_method( cP4, "connected?",RUBY_METHOD_FUNC(p4_connected)   , 0 );
         | 
| 1307 1387 | 
             
                rb_define_method( cP4, "disconnect", RUBY_METHOD_FUNC(p4_disconnect) , 0 );
         | 
| 1308 | 
            -
                rb_define_method( cP4, "reset",  RUBY_METHOD_FUNC(p4_reset), 0 );
         | 
| 1309 1388 |  | 
| 1310 1389 | 
             
                // Running commands - general purpose commands
         | 
| 1311 1390 | 
             
                rb_define_method( cP4, "run", 	RUBY_METHOD_FUNC(p4_run)         ,-2 );
         | 
| @@ -1343,6 +1422,18 @@ void	Init_P4() | |
| 1343 1422 | 
             
                rb_define_method( cP4, "progress", RUBY_METHOD_FUNC(p4_get_progress), 0);
         | 
| 1344 1423 | 
             
                rb_define_method( cP4, "progress=", RUBY_METHOD_FUNC(p4_set_progress), 1);
         | 
| 1345 1424 |  | 
| 1425 | 
            +
                // SSO handling
         | 
| 1426 | 
            +
                rb_define_method( cP4, "loginsso", RUBY_METHOD_FUNC(p4_get_enabled_sso), 0);
         | 
| 1427 | 
            +
                rb_define_method( cP4, "loginsso=", RUBY_METHOD_FUNC(p4_set_enable_sso), 1);
         | 
| 1428 | 
            +
                rb_define_method( cP4, "ssovars", RUBY_METHOD_FUNC(p4_get_sso_vars), 0);
         | 
| 1429 | 
            +
                rb_define_method( cP4, "ssopassresult", RUBY_METHOD_FUNC(p4_get_sso_passresult), 0);
         | 
| 1430 | 
            +
                rb_define_method( cP4, "ssopassresult=", RUBY_METHOD_FUNC(p4_set_sso_passresult), 1);
         | 
| 1431 | 
            +
                rb_define_method( cP4, "ssofailresult", RUBY_METHOD_FUNC(p4_get_sso_failresult), 0);
         | 
| 1432 | 
            +
                rb_define_method( cP4, "ssofailresult=", RUBY_METHOD_FUNC(p4_set_sso_failresult), 1);
         | 
| 1433 | 
            +
                rb_define_method( cP4, "ssohandler", RUBY_METHOD_FUNC(p4_get_ssohandler), 0);
         | 
| 1434 | 
            +
                rb_define_method( cP4, "ssohandler=", RUBY_METHOD_FUNC(p4_set_ssohandler), 1);
         | 
| 1435 | 
            +
             | 
| 1436 | 
            +
             | 
| 1346 1437 | 
             
                // P4::MergeData class
         | 
| 1347 1438 | 
             
                cP4MD = rb_define_class_under( cP4, "MergeData", rb_cObject );
         | 
| 1348 1439 |  |