Class: RStyx::Server::Session
- Inherits:
-
Monitor
- Object
- Monitor
- RStyx::Server::Session
- Defined in:
- lib/rstyx/server.rb
Overview
Session state of a Styx connection.
Constant Summary collapse
- EXECUTE =
These constants are used by Session#permission? and should NOT be changed. The algorithm used depends on it!
0
- WRITE =
1
- READ =
2
Instance Attribute Summary collapse
-
#auth ⇒ Object
Authenticated flag.
-
#fids ⇒ Object
List of active fids on this session.
-
#groups ⇒ Object
Group table.
-
#iounit ⇒ Object
Active iounit for this connection.
-
#msize ⇒ Object
Maximum message size to be used by this session, based on the lesser of the server’s and the client’s msize.
-
#tags ⇒ Object
List of active tags on this session.
-
#user ⇒ Object
User this connection has authenticated against.
-
#version_negotiated ⇒ Object
Flag which is true if version negotiation has been performed on this session.
Instance Method Summary collapse
-
#[](fid) ⇒ Object
Gets the file associated with the indexed FID.
-
#[]=(fid, file) ⇒ Object
Associates a FID with a file.
-
#add_tag(tag) ⇒ Object
(also: #<<)
Adds the given tag to the list of tags in use, first checking to see if it is already in use.
-
#clunk(fid) ⇒ Object
Clunk fid, i.e.
-
#clunk_all ⇒ Object
Clunk all outstanding fids on this connection.
-
#confirm_open(sf, mode) ⇒ Object
Checks that the given file can be opened with the given mode.
-
#execute?(sf) ⇒ Boolean
Check for executable permission for the SFile sf.
-
#flush_all ⇒ Object
Flush all outstanding tags on this session.
-
#has_fid?(fid) ⇒ Boolean
Returns true if fid is associated with some file on this session.
-
#has_tag?(tag) ⇒ Boolean
Returns true if tag is associated with some active message.
-
#initialize(conn) ⇒ Session
constructor
Create a new session.
-
#permission?(sf, mode) ⇒ Boolean
Check the permissions for a given mode.
-
#release_tag(tag) ⇒ Object
(also: #flush_tag)
Called when a message is replied to, releasing tag so it can be used again.
-
#reset_session(msize) ⇒ Object
Reset the session, setting version negotiation flag and iounit.
-
#version_negotiated? ⇒ Boolean
Return true if the session peer has completed version negotiation.
-
#writable?(sf) ⇒ Boolean
Check for write permission for the SFile sf.
Constructor Details
#initialize(conn) ⇒ Session
Create a new session.
- conn
-
The connection object (Server mixin)
693 694 695 696 697 698 699 700 701 |
# File 'lib/rstyx/server.rb', line 693 def initialize(conn) @conn = conn @version_negotiated = false @msize = 0 @user = nil @auth = false @fids = {} @tags = [] end |
Instance Attribute Details
#auth ⇒ Object
Authenticated flag
664 665 666 |
# File 'lib/rstyx/server.rb', line 664 def auth @auth end |
#fids ⇒ Object
List of active fids on this session
667 668 669 |
# File 'lib/rstyx/server.rb', line 667 def fids @fids end |
#groups ⇒ Object
Group table
686 687 688 |
# File 'lib/rstyx/server.rb', line 686 def groups @groups end |
#iounit ⇒ Object
Active iounit for this connection
682 683 684 |
# File 'lib/rstyx/server.rb', line 682 def iounit @iounit end |
#msize ⇒ Object
Maximum message size to be used by this session, based on the lesser of the server’s and the client’s msize.
661 662 663 |
# File 'lib/rstyx/server.rb', line 661 def msize @msize end |
#tags ⇒ Object
List of active tags on this session
670 671 672 |
# File 'lib/rstyx/server.rb', line 670 def @tags end |
#user ⇒ Object
User this connection has authenticated against
678 679 680 |
# File 'lib/rstyx/server.rb', line 678 def user @user end |
#version_negotiated ⇒ Object
Flag which is true if version negotiation has been performed on this session
674 675 676 |
# File 'lib/rstyx/server.rb', line 674 def version_negotiated @version_negotiated end |
Instance Method Details
#[](fid) ⇒ Object
Gets the file associated with the indexed FID. Raises a FidNotFoundException if the fid is not present.
- fid
-
the fid to obtain the associated SFile instance of
745 746 747 748 749 750 |
# File 'lib/rstyx/server.rb', line 745 def [](fid) unless has_fid?(fid) raise FidNotFoundException.new(fid) end return(@fids[fid]) end |
#[]=(fid, file) ⇒ Object
Associates a FID with a file. The FID passed must be checked before using this or the old FID will be forgotten.
- fid
-
the fid to be associated
- file
-
the SFile to associate with fid
734 735 736 737 |
# File 'lib/rstyx/server.rb', line 734 def []=(fid, file) @fids.delete(fid) @fids[fid] = file end |
#add_tag(tag) ⇒ Object Also known as: <<
Adds the given tag to the list of tags in use, first checking to see if it is already in use. Raises a TagInUseException if tag is already in use.
810 811 812 813 814 815 |
# File 'lib/rstyx/server.rb', line 810 def add_tag(tag) if has_tag?(tag) raise TagInUseException.new(tag) end @tags << tag end |
#clunk(fid) ⇒ Object
Clunk fid, i.e. make the server forget about the fid assignment for this connection.
764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 |
# File 'lib/rstyx/server.rb', line 764 def clunk(fid) unless @fids.has_key?(fid) raise FidNotFoundException.new(fid) end sf = self[fid] sf.synchronize do # Get the client using this fid, and see whether the file # is requested to be deleted on clunk. sfc = sf.client(self, fid) if (!sfc.nil? && sfc.orclose?) begin sf.remove rescue Exception => e # if there was a problem removing the file, ignore it end end sf.remove_client(sfc) @fids.delete(fid) end end |
#clunk_all ⇒ Object
Clunk all outstanding fids on this connection.
788 789 790 791 792 793 794 795 796 |
# File 'lib/rstyx/server.rb', line 788 def clunk_all @fids.each_key do |k| begin clunk(k) rescue FidNotFoundException => e # ignore this as we are closing down anyway... end end end |
#confirm_open(sf, mode) ⇒ Object
Checks that the given file can be opened with the given mode. Raises a StyxException if this is not possible.
- sf
-
the SFile to be opened
- mode
-
the open mode
901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 |
# File 'lib/rstyx/server.rb', line 901 def confirm_open(sf, mode) if sf.exclusive? && sf.num_clients != 0 raise StyxException.new("can't open locked file") end openmode = mode & 0x03 case openmode when OREAD unless (sf, READ) raise StyxException.new("read permission denied") end when OWRITE unless (sf, WRITE) raise StyxException.new("write permission denied") end when ORDWR unless (sf, READ) raise StyxException.new("read permission denied") end unless (sf, WRITE) raise StyxException.new("write permission denied") end when OEXEC unless (sf, EXECUTE) raise StyxException.new("execute permission denied") end else # shouldn't happen raise StyxException.new("internal Styx error openmode = #{openmode}: should be between 0 and 3") end # Execute permission is required for a directory in order to # do anything with it if sf.directory? && !execute?(sf) raise StyxException("directory execute permission denied") end if (mode & OTRUNC) != 0 # can't truncate a directory if sf.directory? raise StyxException.new("cannot truncate a directory") end unless (sf, WRITE) raise StyxException.new("need write permissions to truncate a file") end end if (mode & ORCLOSE) != 0 # can't delete a directory on closing if sf.directory? raise StyxException.new("cannot automatically delete a directory") end # we must have write permissions on the parent directory and the file # itself to delete the file on clunking its fid unless (sf.parent, WRITE) raise StyxException.new("need write permissions on the parent directory to delete the file when the fid is clunked") end # TODO: do we need write permissions on the file itself? end end |
#execute?(sf) ⇒ Boolean
Check for executable permission for the SFile sf.
884 885 886 |
# File 'lib/rstyx/server.rb', line 884 def execute?(sf) return((sf, EXECUTE)) end |
#flush_all ⇒ Object
Flush all outstanding tags on this session.
832 833 834 835 836 |
# File 'lib/rstyx/server.rb', line 832 def flush_all @tags.each do |f| flush_tag(t) end end |
#has_fid?(fid) ⇒ Boolean
Returns true if fid is associated with some file on this session.
756 757 758 |
# File 'lib/rstyx/server.rb', line 756 def has_fid?(fid) return(@fids.has_key?(fid)) end |
#has_tag?(tag) ⇒ Boolean
Returns true if tag is associated with some active message
801 802 803 |
# File 'lib/rstyx/server.rb', line 801 def has_tag?(tag) return(!@tags.index(tag).nil?) end |
#permission?(sf, mode) ⇒ Boolean
Check the permissions for a given mode
- sf
-
the file to check against
- mode
-
the mode to check (EXEC, WRITE, or READ)
850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 |
# File 'lib/rstyx/server.rb', line 850 def (sf, mode) if mode < 0 || mode > 2 raise "Internal error: mode should be 0, 1, or 2" end # We bit shift the permissions value so that the mode is # represented by the last bit (all) the fourth to last bit # (group), and the seventh-to-last bit (user). For example, # if we started with a mode of 0755 (binary 111101101, # rwxrwxrwx), and we want to check write permissions, we # shift by one bit so that the value of perms is 1110110, or # (rwxrwxrw). perms = sf. >> mode # Check permissions for 'all' -- the low-order bit unless perms & 0b000_000_001 == 0 return(true) end # Group permissions unless (perms & 0b000_001_000) == 0 # The group has the correct permissions; now we have to find if # the user is a member of the group in question. ug = @groups[@user] unless ug.index(sf.gid).nil? return(true) end end # Owner permissions. This is the final fallback. return(((perms & 0b001_000_000) != 0) && (@user == sf.uid)) end |
#release_tag(tag) ⇒ Object Also known as: flush_tag
Called when a message is replied to, releasing tag so it can be used again.
823 824 825 |
# File 'lib/rstyx/server.rb', line 823 def release_tag(tag) @tags.delete(tag) end |
#reset_session(msize) ⇒ Object
Reset the session, setting version negotiation flag and iounit.
– FIXME: should clunk all outstanding fids and release all outstanding tags on this connection ++
- msize
-
the maximum message size for this connection
721 722 723 724 725 |
# File 'lib/rstyx/server.rb', line 721 def reset_session(msize) # XXX: clunk all outstanding fids and release all outstanding tags @version_negotiated = true @iounit = msize end |
#version_negotiated? ⇒ Boolean
Return true if the session peer has completed version negotiation
706 707 708 |
# File 'lib/rstyx/server.rb', line 706 def version_negotiated? return(@version_negotiated) end |
#writable?(sf) ⇒ Boolean
Check for write permission for the SFile sf.
890 891 892 |
# File 'lib/rstyx/server.rb', line 890 def writable?(sf) return((sf, WRITE)) end |