164 lines
3.0 KiB
Ruby
164 lines
3.0 KiB
Ruby
# -*- coding: binary -*-
|
|
# https://en.wikipedia.org/wiki/Printer_Job_Language
|
|
# See external links for PJL spec
|
|
|
|
module Rex::Proto::PJL
|
|
class Client
|
|
|
|
attr_reader :sock
|
|
|
|
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
|
|
|
|
# List a directory
|
|
#
|
|
# @param pathname [String] Pathname
|
|
# @param count [Fixnum] Number of entries to list
|
|
# @return [String] Directory listing
|
|
def fsdirlist(pathname, count = COUNT_MAX)
|
|
if pathname !~ /^[0-2]:/
|
|
raise ArgumentError, "Pathname must begin with 0:, 1:, or 2:"
|
|
end
|
|
|
|
listing = nil
|
|
|
|
@sock.put(%Q{#{FSDIRLIST} NAME = "#{pathname}" 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 pathname [String] Pathname
|
|
# @param size [Fixnum] Size of file
|
|
# @return [String] File as a string
|
|
def fsupload(pathname, size = SIZE_MAX)
|
|
if pathname !~ /^[0-2]:/
|
|
raise ArgumentError, "Pathname must begin with 0:, 1:, or 2:"
|
|
end
|
|
|
|
file = nil
|
|
|
|
@sock.put(%Q{#{FSUPLOAD} NAME = "#{pathname}" OFFSET=0 SIZE=#{size}\n})
|
|
|
|
if @sock.get(DEFAULT_TIMEOUT) =~ /SIZE=\d+\r?\n(.*)\f/m
|
|
file = $1
|
|
end
|
|
|
|
file
|
|
end
|
|
|
|
end
|
|
end
|