\documentclass {article}
%\documentclass [twocolumn]{article}
\usepackage{amsmath}
\usepackage{indentfirst}
\usepackage{blkarray}
                             % The preamble begins here.
\title{A Platform Independent File Browser}  % Declares the document's title.
\author{Sidney Marshall}      % Declares the author's name.
\date{August 6, 2017 (updated \today)}  % Deleting this command produces today's date.




%allow other brackets in bordermatrix using [] arguments

\makeatletter
\newif\if@borderstar
\def\bordermatrix{\@ifnextchar*{%
  \@borderstartrue\@bordermatrix@i}{\@borderstarfalse\@bordermatrix@i*}%
}
\def\@bordermatrix@i*{\@ifnextchar[{\@bordermatrix@ii}{\@bordermatrix@ii[()]}}
\def\@bordermatrix@ii[#1]#2{%
\begingroup
 \m@th\@tempdima8.75\p@\setbox\z@\vbox{%
  \def\cr{\crcr\noalign{\kern 2\p@\global\let\cr\endline }}%
  \ialign {$##$\hfil\kern 2\p@\kern\@tempdima & \thinspace %
  \hfil $##$\hfil && \quad\hfil $##$\hfil\crcr\omit\strut %
  \hfil\crcr\noalign{\kern -\baselineskip}#2\crcr\omit %
  \strut\cr}}%
 \setbox\tw@\vbox{\unvcopy\z@\global\setbox\@ne\lastbox}%
 \setbox\tw@\hbox{\unhbox\@ne\unskip\global\setbox\@ne\lastbox}%
 \setbox\tw@\hbox{%
  $\kern\wd\@ne\kern -\@tempdima\left\@firstoftwo#1%
   \if@borderstar\kern2pt\else\kern -\wd\@ne\fi%
  \global\setbox\@ne\vbox{\box\@ne\if@borderstar\else\kern 2\p@\fi}%
  \vcenter{\if@borderstar\else\kern -\ht\@ne\fi%
   \unvbox\z@\kern-\if@borderstar2\fi\baselineskip}%
   \if@borderstar\kern-2\@tempdima\kern2\p@\else\,\fi\right\@secondoftwo#1 $%
 }\null \;\vbox{\kern\ht\@ne\box\tw@}%
\endgroup
}
\makeatother

\DeclareMathOperator{\sech}{sech}
\DeclareMathOperator{\csch}{csch}
\DeclareMathOperator{\arc}{arc}
\DeclareMathOperator{\real}{real}
\DeclareMathOperator{\imag}{imag}
\DeclareMathOperator{\AGM}{AGM}
%\DeclareMathOperator{\Re}{Re}
%\DeclareMathOperator{\Im}{Im}


\usepackage{enumitem}

\newcommand{\ip}[2]{(#1, #2)}
                             % Defines \ip{arg1}{arg2} to mean
                             % (arg1, arg2).

%\newcommand{\ip}[2]{\langle #1 | #2\rangle}
                             % This is an alternative definition of
                             % \ip that is commented out.

% from latex.ltx

\begin{document}             % End of preamble and beginning of text.

\maketitle                   % Produces the title.
%\addappheadtotoc
\tableofcontents

\newpage

[{\it The File Browser is still a work in progress so details are sure
    to change. It is currently useful enough to maintain the
    squaredancing website.}]

\begin{abstract}

There is a need for a platform-independent file browser that will work
on Microsoft and Linux platforms. This Java program attempts to fill
this need. It is loosely modeled after the \verb|WinSCP| program and
the windows file browser. The current program allows transfers between
two file systems. The file systems can be either local or remote or
one of each. It also allows opening a terminal or shell window on a
remote machine.

It is implemented entirely in Java and should run on any platform
supporting Java 8.

\end{abstract}

\section{File Names and Session Names}

Local file names are either of the form ``\verb|/c:/...|'' (windows)
or ``\verb|/xxx...|'' (Linux). For remote files the format is
``\verb|//user@x.y.z/c:/...|'' (windows assuming an sftp server) or
``\verb|//user@x.y.z/...|'' (Linux). For remote file names if there is
no closing `\verb#/#' then the home directory (obtained by \verb|pwd|
is used (as in \verb|//swm@glados.cs.rit.edu|). Using remote file
names causes the file browser to open up an sftp connection. All
opened sftp connections are visible at the top-level of the displayed
file tree. All functions work for remote files except noticing changed
files --- a refresh button must be pressed to resynchronize the file
browser's display to match the remote files.

A session name is of the form \verb|user@host| and is used for remote
shells.

Note the difference between \verb|//user@host| for remote files and
\verb|user@host| for session names.

Passwords are kept (somewhat encrypted) in a file named
\verb|.filebrowserrc| in the home directory so passwords need to be
entered only once. Currently there is no option to suppress this
feature. This may be a security problem.

Transferring files between two remote machines viewed through
different file browser invocations also works.

%\section{Running From Scripts (not implemented yet)}
%
%The file browser can be run from a script. Note that in a file tree
%one tree is always a subset of another. A make-like facility will
%order the transfer requests for maximum parallelism.
%
%There is a mode that previews the copies without doing anything.
%
%\subsection{Script Format}
%
%target left
%
%target right
%
%target both
%
%--------
%
%synchronize
%
%mirror
%
%preview changes
%
%delete files
%
%--------
%
%\begin{verbatim}
%mode: mirror | 
%[tree node] -> [tree node]
%![relative tree node]
%
%mode: mirror | 
%[tree node] <-> [tree node]
%![relative tree node]
%\end{verbatim}
%
%Several patterns can be given after on another. The \verb|!| symbol
%restricts the copy from descending into the specified (relative)
%node. It is not an error if the node does not exist.
%
%\subsection{Parallel criteria}
%
%No set of files can be used as a source until all transfers to these
%files complete.
%
%Bi-directional transfers wait for all transfers to either
%directory. Transfers from bi-directional transfers (either directory)
%wait until the bi-directional transfer completes.
%
%Transfers start as early as possible.
%
%Transfers are queued in the order that they appear in the script.
%
%A transfer $A \rightarrow B$ is blocked if there are any previously
%specified uncompleted transfers:
%
%\begin{description}[style=multiline,leftmargin=.6in]
%  \item[$X \rightarrow A$] The data $A$ might not be available
%  \item[$X \rightarrow B$] The writing of data to $B$ would not be
%    properly synchronized
%  \item[$A \rightarrow X$] Does not block --- can proceed in parallel
%  \item[$B \rightarrow X$] Want to copy data from $B$ before being
%    overwritten
%\end{description}
%
%A transfer $A \leftrightarrow B$ is blocked by any operations using $A$ or $B$ and blocks any transfer using $A$ or $B$.
%
%Trees that are subtrees are treated the same as if they were the
%parent tree. No attempt is made to optimize \verb|!| clauses --- the
%optimization assumes that the \verb|!| clauses are not present.

%\section{Browser Windows}
%
%\begin{tabbing}
%xx\=xx\=xx\=xx\=xx\=xx\=xx\=xx\=xx\=xx\=xx\=xx\=xx\=\kill
%// Get and process pagegroups from master table substitutions \\
%Table subs = new Table("select * from substitutions order by pagegroup", \\
%\>\>\>\>\>\>\>\>\>\>\> "pagegroup", "substitutions"); \\
%ArrayList$<$String$>$ subsLine; \\
%while((subsLine = subs.next()) != null) \{ \\
%\>//System.out.println("subsLine: " + subsLine); \\
%\>String pagegroup = subsLine.get(0); \\
%\> // run substitution sql to get list of substitutions for pagegroup \\
%\>Table subsList = new Table(subsLine.get(1)); \\
%\>ArrayList$<$String$>$ subsListLine; // actual substitutions vector \\
%\>while((subsListLine = subsList.next()) != null) \{ \\
%\>\>//System.out.println("subsListLine: " + subsListLine); \\
%\>\>String filename = subsListLine.get(0); \\
%\>\>FileWriter out = null; \\
%\>\>if(filename != null) \{ \\
%\>\>\>out = new FileWriter(filename); \\
%\>\>\} \\
%\>\>// get scripts for pagegroup \\
%\>\>ArrayList$<$String$>$ scriptsLine; \\
%\>\} \\
%\} \\
%\end{tabbing}

\section{Starting the File Browser}

The file browser should run on any platform that supports Java.

There are five ways to use the file browser.

Started with no arguments or clicking on the program icon the file
browser will start with a single file system Window on the root of the
local file system.

If the first argument is \verb|-ssh| all subsequent arguments are
interpreted as session names of the form \verb|user@host| and a remote
shell is opened for each argument.

If the first argument is \verb|-diff| the next two arguments are
interpreted as \verb|URL|s and a diff is performed between the two
files.

Otherwise, if there are exactly two arguments then a dual Window is
opened using the arguments as \verb|URL|s for the two sides of the
dual Window.

Otherwise, (for one or three or more arguments) each argument is
interpreted as a \verb|URL| and a separate single file system Window
is opened on each one.

Otherwise, if there are no arguments, a single file system Window is
opened on the root of the file system.

Link support is not yet complete and will probably never work for
Microsoft file systems.

\section{The Seven Types of Windows}

There are seven types of windows used by the file browser. They are:

\begin{description}[style=multiline,leftmargin=1.1in]
  \item[Single File] Displays files and directories
  \item[Dual] Displays and updates between two directories
  \item[Shell] A shell on a remote system
  \item[Edit] An editor generally based on a file
  \item[Find/Replace] does a find or replace on parent window
  \item[Diff] Shows the results of differencing two files
  \item[Progress] Shows the progress of a file transfer
\end{description}

\subsection{The Single File System Window}

The single file system Window somewhat mimics the windows file
browser except it works on remote directories and files too.

A list of files, directories, and links (local or remote) are
displayed. The columns are the name of the file/directory, the size,
and the modification date. Directories and file system roots have a
gray background. Links have a yellow background and the size field is
replaced by the link target.

By clicking on the \verb|Tree View| button a tree view can be seen
side-by-side with the list view. The boundary between the two views
can be moved with the mouse. When viewing the tree view clicking on
the \verb|List View| button the display reverts to a single window
displaying the list of files and directories. Moving the vertical
divider will also display/hide the tree view.

\subsubsection{Buttons etc.}

The top row of buttons are 

\begin{description}[style=multiline,leftmargin=1.6in]
  \item[Left Arrow] Go to the last-viewed directory, a.k.a. ``back''
  \item[Up Arrow] Goto parent directory
  \item[Right Arrow] Go to the next-viewed directory,
    a.k.a. ``forward''
  \item[Show/Hide dot files] Show or hide files/directories beginning
    in ``.''
  \item[Tree View / List view] Show or hide the tree view
  \item[Clone] Start another file browser displaying the same
    directory as the current one
\end{description}

Note: Using the ``up arrow'' to get to the top of the file hierarchy
will give, in the drop-down menu, a list of all remembered
directories, both local and remote.

The next row contains an editable text field that generally displays
the directory being displayed. Both drag and drop and clipboard cut
and paste work on this text field. Editing this text field and
clicking the \verb|Go| button will display the directory in the text
field. If the directory does not exist then the deepest existing
directory along the specified path is displayed.
The \verb|Add| button adds the currently selected directory to the top
level \verb|file system root(s)| drop down menu.
The \verb|Delete| button removes the currently selected directory to
the top level \verb|file system root(s)| drop down menu.

The display area displays the tree of directories on the left (if not
hidden) and the files of the selected directory on the right.

Right clicking on a (remote) directory on the right of the display
will bring up a terminal or shell window on the same file system.

Right clicking on a file on the right of the display will bring
up an editor on this file.

The bottom row of buttons are used for debugging and are

\begin{description}[style=multiline,leftmargin=1.6in]
  \item[Print Selected Path] Prints the selected path on stdout
  \item[Print Tree] Prints the displayed tree
  \item[Delete tree] Deletes the selected file or tree (use carefully
    --- there is no undo!)
  \item[Touch File] ``Touches'' or creates the file in the editable file name window
  \item[Create Directory] Creates a directory named in the editable file name window
\end{description}

Drag and Drop works in this type of window.

\subsection{The Dual Window}

If the file browser is started with exactly two directories then a combined Window is generated. This display compares files from two file systems (this could be the same file system) side by side.

A combined view allows comparison of two directories (or files?) and
an update operation that, with the right options, will transfer files
or create directories to make the two directories mirrors of each
other.

\subsubsection{Buttons etc.}

The top line of the display is

\begin{description}[style=multiline,leftmargin=1.6in]
  \item[(left) Up Arrow] Go to left-side parent directory
  \item[(left) Text window] Path of left-side directory
  \item[(left) Down arrow] Drop down menu of left-side sub directories
  \item[refresh (button)] Refreshes display by comparing left and
    right directories; right-clicking this button will check file
    dates with no daylight savings adjustments
  \item[(right) Up Arrow] Go to right-side parent directory
  \item[(right) Text window] Path of right-side directory
  \item[(right) Down arrow] Drop down menu of right-side sub
    directories
\end{description}

The body of the display is a table with seven columns:

\begin{description}[style=multiline,leftmargin=1.6in]
  \item[x] Checked means this file or directory will be copied or
    deleted when the Synchronized button is pressed
  \item[path] Suffix to actual paths (the prefix is in the left or
    right text window)
  \item[left size] Size (in bytes) of left-side file or directory
  \item[left date] Date of left-side file or directory
  \item[icon] Icon indicating direction and type of transfer (see
    below)
  \item[right size] Size (in bytes) of right-side file or directory
  \item[right date] Date of right-side file or directory
\end{description}

A link will have a yellow background and the size field will be
replaced with the target of the link.

Clicking on the left check box will reverse the checked state.

Clicking on a (direction) icon will reverse its direction.

Right-clicking on a size or date of a directory will bring up a single
file system window on the corresponding directory.  Right-clicking on
a size or date of a file will bring up a file editor on the
corresponding file.

Right-clicking on the direction icon will bring up an edit window
containing the \verb|diff| between the left and right files. This only
works for files.

The bottom buttons are

\begin{description}[style=multiline,leftmargin=1.6in]
  \item[Select All] Select all lines
  \item[Check All] Check all lines
  \item[Check Selected] Check all selected lines
  \item[Target Left] Make the target for selected lines the left-side
    file or directory
  \item[Target right] Make the target for selected lines the
    right-side file or directory
  \item[Unselect All] Unselect all lines
  \item[Uncheck All] Uncheck all lines
  \item[Uncheck Selected] Uncheck all selected lines
  \item[Default Target] Make the target for selected lines the default
  \item[Synchronize] Execute the specified transfer for all checked
    lines; right-clicking this button will only update file dates
\end{description}

Below the bottom buttons is a line of all 16 possible icons. Clicking
on one of these cons will select all lines in the table with this
icon. The direction of the ``arrow'' points to the side that will be
modified (created, deleted, or overwritten). The colors indicate:

\begin{description}[style=multiline,leftmargin=0.7in]
  \item[Green] Creation of file or directory
  \item[Red] Overwriting or deleting of a file or directory
  \item[Magenta] Overwriting a newer file with an older file
  \item[Brown] Overwriting a file with a directory or a directory with
    a file
\end{description}

The icons are:

\begin{description}[style=multiline,leftmargin=2.6in]
  \item[Left Overwrite Newer Right] Overwrite left file with a newer
    right file
  \item[Left Overwrite Older Right] Overwrite left file with an older
    right file
  \item[Left Create File] Copy right file to a new left file
  \item[Left Create Directory] Copy right directory tree to a new left
    directory
  \item[Left Delete Directory] Delete left directory
  \item[Left Delete File] Delete left file
  \item[Right Directory Overwrite Left File] Copy right directory over
    left file
  \item[Right File Overwrite Left Directory] Copy right file over left
    directory
  \item[Right Overwrite Newer Left] Overwrite right file with a newer
    left file
  \item[Right Overwrite Older Left] Overwrite right file with an older
    left file
  \item[Right Create File] Copy left file to a new right file
  \item[Right Create Directory] Copy left directory tree to a new\\
    right directory
  \item[Right Delete Directory] Delete right directory
  \item[Right Delete File] Delete right file
  \item[Left Directory Overwrite Right File] Copy left directory over
    right file
  \item[Left File Overwrite Right Directory] Copy left file over right
    directory
\end{description}

Below each icon is a fraction. The numerator indicates how many lines
with this icon are checked. The denominator indicates the total number
of this kind of icon (checked or unchecked).

The last line indicates the file or directory currently being worked
on.

To update only file dates the recommended procedure is to do a normal
update first and then right click \verb|refresh| and then (after
possibly checking appropriate files and changing directions) right
click \verb|Synchronize|.

\subsection{The Terminal or Shell Window}

A Shell Window is a shell on a remote system. You can type commands
and see results. Most terminal controls are implemented and more are
being implemented. The terminal or shell Window is quite usable for
most purposes.

Right clicking on the body of a shell window will bring up a
\verb|FileBrowser| on the home directory.

X11-window tunneling is not implemented as I haven't figured out how
to do this (or have many other people).

\subsection{The Edit Window}

It is possible to bring up an edit window on a local or remote file by
right-clicking on the file in the Single File System Window or by
clicking on the date or size in the dual window. This is an ordinary
editing window which should display the original contents of the file
before you start editing. The buttons below are:

\begin{description}[style=multiline,leftmargin=1.6in]
  \item[Read File] Rereads the contents of the file into the edit window
  \item[Write File] Writes the current contents of the edit window
    back to the file
  \item[Print] Prints the current contents of the edit window
\end{description}

\subsection{The Find-Replace Window}

Right clicking in an Edit Window or a Command Window brings up a
Find-Replace Window. There are two editable fields (find and replace)
and four buttons in the window:

\begin{description}[style=multiline,leftmargin=1.2in]
  \item[Find] Finds and selects the next occurrence of the text in the
    adjacent find field
  \item[Replace] Replaces the selected text with the contents of the
    adjacent replace field
  \item[Replace/Find] Does a replace operation followed by a find
    operation
    \item[Find Lines] Finds a particular line number
\end{description}

If a \verb|Find| search does not find any further
matches then the selection is set to the beginning of the file and the
status line displays \verb|not found|. This means the search will
start at the beginning, i.e., the search will start at the beginning
the next time a search is attempted.

The status line also contains a check box on the right labelled
\verb|Ignore Case|. If checked, the search is done without requiring
that the case of the search string maches. If unchecked, the search
string must match exactly, including case.

The \verb|Replace| operations modify the contents of the associated
Edit Window.

The \verb|Find Lines| will set the cursor at the line number indicated
by the search window.

\subsection{The File Difference Window}

This window appears after right-clicking on an arrow in the dual
window. It displays the difference between the left and right files in
a diff format.

\subsection{The Progress Window}

This window appears automatically when there is a transfer to or from
a remote file. It indicates the name of the file and the percentage of
the file transfer completed.

\section{Mouse Button Summary}

Right button

Edit Window (including FileEditWindow)

bring up find/replace window

Single Window File Browser

on directory (tree or file view)

bring up a shell window

on file

bring up File Edit Window

Dual Window File Browser

length or date field

bring up File Edit Window

direction arrow

bring up diff window of files on both sides

shell window

bring up file browser

\section{Drag and Drop}

\section{File Transfers [This is not yet implemented.]}

The target file has a \verb|.partfile| extension added to it. When the
file transfer is successfully completed this \verb|.partfile| file is
moved to a file with the proper file name. If the transfer does not
complete successfully then the \verb|.partfile| file is left and the
original target file is untouched (leaving the file date intact).

\subsection{Resuming A File Transfer}

Files are transferred to a temporary file with a \verb|.partfile|
suffix and, on successful completion of the transfer, are moved to the
actual file name. If a file transfer is interrupted in the middle the
\verb|.partfile| file will remain. The file transfer can be resumed by
appending to the \verb|.partfile| file.

To determine if a transfer can be resumed or must be restarted, the
file dates of the source file and the \verb|.partfile| file are
compared. If the \verb|.partfile| file's date is more recent than the
source file's date then the transfer can be resumed. Otherwise, the
file transfer must be started over from the beginning as the source
file's contents have changed.

It is always safe to overwrite or delete the \verb|.partfile|
file. For now, transfers are always restarted from the beginning.

\section{Discussion on File Name Encodings}

The original \verb|jsch| program assumes that file names are legal
UTF-8 strings. Unfortunately, windows file names are encoded in a
variant of ISO-8859 resulting in file names that are illegal UTF-8
names. The conversion process between the file name bytes and UTF-8
loses information and the transformation is not reversible. I have
modified the \verb|jsch| program to encode file names (both in and
out) as \verb|URI|'s which can handle an arbitrary sequence of
bytes. This is done by encoding problematical bytes with the sequence
\verb|%xx| where \verb|xx| is the hex representation of the
problematical byte. Per cent signs are encoded as \verb|%25| and other
bytes that could result in parsing problems for a \verb|URI| are also
appropriately encoded.

Whereas Linux allows any character except \verb|null| and \verb|/| in
a file name, windows is more particular and has a longer list of
characters not allowed in a file name. If a Linux file name contains a
byte that is an illegal in a windows file name then the transfer will
fail. I am not sure what to do about this.

Note that no attempt is made to convert a legal UTF-8 name to a
re-encoded ISO-8859 windows name.

\subsection{URIs, URLs, and URNs}

A \verb|URI| is a uniform resource identifier while a \verb|URL| is a
uniform resource locator. Hence every \verb|URL| is a \verb|URI|,
abstractly speaking, but not every \verb|URI| is a \verb|URL|. This is
because there is another subcategory of \verb|URI|s, uniform resource
names (\verb|URN|s), which name resources but do not specify how to
locate them. The mailto, news, and isbn \verb|URI|s are examples of
\verb|URN|s.

A \verb|URI| represents a reference in the syntactic sense defined by
RFC 2396. A \verb|URI| may be either absolute or relative. A
\verb|URI| string is parsed according to the generic syntax without
regard to the scheme, if any, that it specifies. In other words, a
\verb|URI| is little more than a structured string that supports the
syntactic, scheme-independent operations of comparison, normalization,
resolution, and relativization.

A \verb|URL|, by contrast, represents the syntactic components of a
\verb|URL| together with some of the information required to access
the resource that it describes. A \verb|URL| must be absolute, that
is, it must always specify a scheme. A \verb|URL| string is parsed
according to its scheme. In other words, a \verb|URL| is a structured
string that supports the syntactic operation of resolution as well as
the network I/O operations of looking up the host and opening a
connection to the specified resource.

\section{Comments on jsch --- the remote SSH Library}

The library \verb|jsch| is an implementation of the \verb|SSH|
protocol written entirely in Java. The library allows setting up a
\verb|SSH| session and then opening up an \verb|sftp| or \verb|ssh|
channel. I have modified this library to take file names with non
UTF-8 file names. This was accomplished by duplicating the original
library code for \verb|put|, \verb|get|, \verb|ls|, \verb|readLink|,
\verb|symLink|, \verb|rename|, \verb|rm|, \verb|setMtime|,
\verb|rmdir|, \verb|mkdir|, \verb|stat|, \verb|lstat|, \verb|setStat|,
and \verb|getHome| to code that takes \verb|URI|s instead of Strings.

I have not yet figured out how to tunnel X11 over \verb|SSH|.

\end{document}               % End of document.
