218 lines
4.1 KiB
Ruby
218 lines
4.1 KiB
Ruby
# -*- coding: binary -*-
|
|
|
|
# https://en.wikipedia.org/wiki/Printer_Job_Language
|
|
# See external links for PJL spec
|
|
|
|
module Rex::Proto::PJL
|
|
class Client
|
|
|
|
def initialize(sock)
|
|
@sock = sock
|
|
end
|
|
|
|
# Begin a PJL job
|
|
#
|
|
# @return [void]
|
|
def begin_job
|
|
@sock.put("#{UEL}#{PREFIX}\n")
|
|
end
|
|
|
|
# End a PJL job
|
|
#
|
|
# @return [void]
|
|
def end_job
|
|
@sock.put(UEL)
|
|
end
|
|
|
|
# Send an INFO request and read the response
|
|
#
|
|
# @param category [String] INFO category
|
|
# @return [String] INFO response
|
|
def info(category)
|
|
categories = {
|
|
:id => Info::ID,
|
|
:status => Info::STATUS,
|
|
:variables => Info::VARIABLES,
|
|
:filesys => Info::FILESYS
|
|
}
|
|
|
|
unless categories.has_key?(category)
|
|
raise ArgumentError, "Unknown INFO category"
|
|
end
|
|
|
|
@sock.put("#{categories[category]}\n")
|
|
@sock.get(DEFAULT_TIMEOUT)
|
|
end
|
|
|
|
# Get version information
|
|
#
|
|
# @return [String] Version information
|
|
def info_id
|
|
id = nil
|
|
|
|
if info(:id) =~ /"(.*?)"/m
|
|
id = $1
|
|
end
|
|
|
|
id
|
|
end
|
|
|
|
# Get environment variables
|
|
#
|
|
# @return [String] Environment variables
|
|
def info_variables
|
|
env_vars = nil
|
|
|
|
if info(:variables) =~ /#{Info::VARIABLES}\r?\n(.*?)\f/m
|
|
env_vars = $1
|
|
end
|
|
|
|
env_vars
|
|
end
|
|
|
|
# List volumes
|
|
#
|
|
# @return [String] Volume listing
|
|
def info_filesys
|
|
filesys = nil
|
|
|
|
if info(:filesys) =~ /\[\d+ TABLE\]\r?\n(.*?)\f/m
|
|
filesys = $1
|
|
end
|
|
|
|
filesys
|
|
end
|
|
|
|
# Get the ready message
|
|
#
|
|
# @return [String] Ready message
|
|
def get_rdymsg
|
|
rdymsg = nil
|
|
|
|
if info(:status) =~ /DISPLAY="(.*?)"/m
|
|
rdymsg = $1
|
|
end
|
|
|
|
rdymsg
|
|
end
|
|
|
|
# Set the ready message
|
|
#
|
|
# @param message [String] Ready message
|
|
# @return [void]
|
|
def set_rdymsg(message)
|
|
@sock.put(%Q{#{RDYMSG} DISPLAY = "#{message}"\n})
|
|
end
|
|
|
|
# Initialize a volume
|
|
#
|
|
# @param volume [String] Volume
|
|
# @return [void]
|
|
def fsinit(volume)
|
|
if volume !~ /^[0-2]:$/
|
|
raise ArgumentError, "Volume must be 0:, 1:, or 2:"
|
|
end
|
|
|
|
@sock.put(%Q{#{FSINIT} VOLUME = "#{volume}"\n})
|
|
end
|
|
|
|
# Query a file
|
|
#
|
|
# @param path [String] Remote path
|
|
# @return [Boolean] True if file exists
|
|
def fsquery(path)
|
|
if path !~ /^[0-2]:/
|
|
raise ArgumentError, "Path must begin with 0:, 1:, or 2:"
|
|
end
|
|
|
|
file = false
|
|
|
|
@sock.put(%Q{#{FSQUERY} NAME = "#{path}"\n})
|
|
|
|
if @sock.get(DEFAULT_TIMEOUT) =~ /TYPE=(FILE|DIR)/m
|
|
file = true
|
|
end
|
|
|
|
file
|
|
end
|
|
|
|
# List a directory
|
|
#
|
|
# @param path [String] Remote path
|
|
# @param count [Integer] Number of entries to list
|
|
# @return [String] Directory listing
|
|
def fsdirlist(path, count = COUNT_MAX)
|
|
if path !~ /^[0-2]:/
|
|
raise ArgumentError, "Path must begin with 0:, 1:, or 2:"
|
|
end
|
|
|
|
listing = nil
|
|
|
|
@sock.put(%Q{#{FSDIRLIST} NAME = "#{path}" ENTRY=1 COUNT=#{count}\n})
|
|
|
|
if @sock.get(DEFAULT_TIMEOUT) =~ /ENTRY=1\r?\n(.*?)\f/m
|
|
listing = $1
|
|
end
|
|
|
|
listing
|
|
end
|
|
|
|
# Download a file
|
|
#
|
|
# @param path [String] Remote path
|
|
# @return [String] File as a string
|
|
def fsupload(path)
|
|
if path !~ /^[0-2]:/
|
|
raise ArgumentError, "Path must begin with 0:, 1:, or 2:"
|
|
end
|
|
|
|
file = nil
|
|
|
|
@sock.put(%Q{#{FSUPLOAD} NAME = "#{path}" OFFSET=0 SIZE=#{SIZE_MAX}\n})
|
|
|
|
if @sock.get(DEFAULT_TIMEOUT) =~ /SIZE=\d+\r?\n(.*)\f/m
|
|
file = $1
|
|
end
|
|
|
|
file
|
|
end
|
|
|
|
# Upload a file
|
|
#
|
|
# @param lpath [String] Local path
|
|
# @param rpath [String] Remote path
|
|
# @return [Boolean] True if the file was uploaded
|
|
def fsdownload(lpath, rpath)
|
|
if rpath !~ /^[0-2]:/
|
|
raise ArgumentError, "Path must begin with 0:, 1:, or 2:"
|
|
end
|
|
|
|
file = File.read(lpath)
|
|
|
|
@sock.put(
|
|
%Q{#{FSDOWNLOAD} FORMAT:BINARY SIZE=#{file.length} NAME = "#{rpath}"\n}
|
|
)
|
|
|
|
@sock.put(file)
|
|
@sock.put(UEL)
|
|
|
|
fsquery(rpath)
|
|
end
|
|
|
|
# Delete a file
|
|
#
|
|
# @param path [String] Remote path
|
|
# @return [Boolean] True if the file was deleted
|
|
def fsdelete(path)
|
|
if path !~ /^[0-2]:/
|
|
raise ArgumentError, "Path must begin with 0:, 1:, or 2:"
|
|
end
|
|
|
|
@sock.put(%Q{#{FSDELETE} NAME = "#{path}"\n})
|
|
|
|
!fsquery(path)
|
|
end
|
|
|
|
end
|
|
end
|