Saturday, August 26, 2017

Remote execution needing root access

Using a program on a remote system that needs root privileges and transferring the output to the local system.

The problem:
My scanner is attached to an old computer, let's call it remote-host.  The installed program that runs it needs root privileges, and outputs a PNM image.  (It needs to be run with sudo because the manufacturer did not supply a Linux driver that handled the scanner, and some kind member of the Ubuntu community wrote one and cut some corners.)
I want a single command that I can run on another computer, say local-host, that will scan whatever is on the scanner plate, and save the result as a JPEG in a specified file.

This solution worked:

I made a bash script, scanto, taking one argument
--- the path to the ultimate JPEG file, without
the .jpg extension, and I put it in my path.
Thus, for instance, the terminal command:
scanto fan
saves the scanned image in the file fan.jpg


Here are the contents of the script:

******************************************

#!/bin/bash
# file scanto
# AOF 25-8-2017

[ $# -eq 0 ] \
        && echo Needs an argument  \
        && echo -- an output filename, without extension \
        && exit

echo WARNING:
echo Existing files $1.pnm and $1.jpg will be overwritten!
echo Type ctrl-C next if you don't want that to happen.

echo Preparing to scan on remote-host
echo You will be asked for your privileged password
echo '#!/bin/bash' > scan.sh
echo 'sudo scanimage > ./scratch/scans/temp.pnm' >> scan.sh
ssh myname@remote-host 'bash -s' < scan.sh
echo page scanned to file scratch/scans/temp.pnm on remote-host

echo Preparing to transfer the file from remote-host
echo You will be asked again for your privileged password
scp myname@remote-host:scratch/scans/temp.pnm $1.pnm
echo scanned page copied to $1.pnm

echo Making a JPEG version:
convert $1.pnm $1.jpg
echo JPEG version now in $1.jpg

********************************

The only essential lines are:

echo '#!/bin/bash' > scan.sh
echo 'sudo scanimage > ./scratch/scans/temp.pnm' >> scan.sh
ssh myname@remote-host 'bash -s' < scan.sh
scp myname@remote-host:scratch/scans/temp.pnm $1.pnm
convert $1.pnm $1.jpg


The first two lines create a shell script, scan.sh
The third line uses ssh (secure shell) to execute scan.sh on the remote system, with root privileges.
The fourth line uses scp (secure copy) to copy temp.pnm to the local system.
The last line uses the convert utility to make a JPEG version.

The script also leaves a PNM version on the local system. This is the raw scan, and is useful if I want to use gimp to modify the image.  Add a line with rm $1.pnm  to the script if you don't want this file.  The script also leaves behind a copy of the scan on the remote host, but that file is overwritten each time scanto is called.

I have to be a sudoer on the remote-host, and I have to give my password twice, as the script executes.  I could not see a secure way to give it just once.
                                                           

Printing from Windows and Android on a "classic printer" attached to USB on Ubuntu

I use a ten-year-old computer running Ubuntu 14.04 as a print server for the house, and it does a little bit of file-serving as well.  I don't want to burden it with any other heavy applications, because it can't take it.

It serves the printer using CUPS.

I gave it a static IP address (192.168.1.x) on the domestic network and then I could easily install it as the default printer for all the Linux and Windows machines we have.

The Android devices (phones and tablets) were more of a problem.  Google Cloud Print would work, but required me to run Chrome on the server, and Chrome is heavy. The solution I settled on was to use the app Let's Print Droid. This finds the CUPS server easily and sets itself up.  I can then 'share' in any app that allows that, and select Let's Print Droid.



Thursday, February 2, 2017

Using an external package with the Java Development Kit

External packages can be accessed once the compiler can find them.  They usually come in a .jar file. There is lots of advice online about how to tell javac to find them.  The three usual ways are to (1) reset the CLASSPATH environmental variable, (2) use the command-line parameter  -cp, or (3) put the .jar file in some ~\jre\lib\ext directory.

The method least likely to have later unwanted side-effects is (2).  To keep it simple, I put a customised version of javac and java in the working directory where I have the source of
my java program.

Here's an example:   The package JGraphT has classes and methods that do all the standard tasks that you might want on a graph. I wanted to use the Bron-Krombosch algorithm to find a maximum independent set of nodes. I found the package at www.jgrapht.org, downloaded it and put it in my directory $HOME/programs/java.  The .jar file I needed was then:

$HOME/programs/java/jgrapht-1.0.1/lib/jgrapht-core-1.0.1.jar

I made executable shell scripts myjavac and myjava, with the following content:

myjavac:

#!/bin/sh
# file myjavac
# Uses java with classpath to include jgrapht package(s)
javac -cp $HOME/programs/java/jgrapht-1.0.1/lib/jgrapht-core-1.0.1.jar \
$1

myjava:

#!/bin/sh
# file myjava
# runs a java class with a main, adding jgrapht package(s)
# and the current directory
# to the classpath
java -cp $HOME/programs/java/jgrapht-1.0.1/lib/jgrapht-core-1.0.1.jar:. \
$1

Notice the :. that adds the current directory to CLASSPATH, as well as the directory that has the JGraphT package.  I put the following lines into my java source:

import org.jgrapht.*;
import org.jgrapht.graph.*;
import org.jgrapht.alg.*;

Then I just went ahead as usual, using 

myjavac <ClassName>.java 

to compile and 

myjava <ClassName>

to execute, where <ClassName> stands for the name of my source file, instead of javac and java. If you needed to use any other command-line parameters with javac, you would have to make the obvious modifications.  


Monday, November 14, 2016

Replacing quarter-glass on a Toyota

The quarter-glass is the little side window at the back. People break them to get in, and they have to be replaced.  We had to put one in today, and I looked on YouTube.  This guy demonstrated how to do it, and he practically dismantled the whole door, so I thought this post might be helpful.

The main thing is that you have to move the pillar separating the main rear window from the quarter-glass, in order to get the new glass (in its rubber seals) in. You don't have to take the pillar out, just move it enough at the top end.
Roll down the main rear window all the way. Pull the rubber seals off near the pillar. The pillar is attached to the door-frame at the top by one or two phillips-head screws. These might be under or over the frame.  There were two screws underneath in that YouTube video. On our car, there was just one screw, on top. One the screw was out, we could move the pillar enough to get the job done, without breaking anything.
Take your time. Make sure all the seals are fitted back properly, that the main window closes easily, and that the screw fits back in.
I suppose that on some models the pillar may not move enough, and then you are going to have to take down the whole main window, like our friend on YouTube.  Just judge for yourself how far the pillar will move when freed at the top, without the use of excessive force.  If you break it, don't blame me.

Saturday, September 3, 2016

Toggle full-screen

F11 toggles between full-screen mode and normal mode.  Use it to get back those bars and tabs at the top of your screen, if they've gone away.

Monday, September 21, 2015

DOS and UNIX line breaks

Here are my scripts 2unix and 2dos, which convert a given text file to one with guaranteed UNIX line breaks or guaranteed DOS line breaks:


#!/bin/sh
# script 2unix
# AOF 14-6-2-05
# make $1 have LF line breaks
# remove all CR:
sed -i 's/\r//' $1
echo $1 now has only LF \(UNIX\) line breaks.
echo \(To view them use cat -e $1.\)



#!/bin/sh
# script 2dos
#AOF 14-6-2-15
# make $1 have CRLF line breaks
# first remove all CR:
sed -i 's/\r//' $1
# then add CR before each LF:
sed -i 's/$/\r/' $1
echo $1 now has only CRLF \(DOS\) line breaks.
echo To view them use cat -e $1.



Thursday, September 10, 2015

LaTeX: Putting answers to selected exercises in an appendix to a book

The LaTeX package answers is designed to deal with this.  Most of the online help relates to using it with an article documentclass.    I used it like this, in a book using the memoir documentclass (which allows both A5 (option a5paper) and US Trade (option ebook) paper sizes.  The bit that caused trouble, and which is handled here, is to make sure that the solution is fully and correctly labelled with the coordinates of the exercise, including the subsection number and the sequence number in the subsection, taking account of the fact that only certain numbers in the sequence have solutions.

In preamble:

\usepackage{answers}
%Exercise:
\newtheorem{Exc}{Exercise}[subsection]
%exercise without answer:
\newenvironment{ex}{\begin{Exc}\normalfont}{\end{Exc}}
%exercise with answer in appendix:
\newenvironment{exw}{\begin{Exc}%
\Writetofile{answers}{\textbf{\thesubsection.\arabic{Exc}}}%
$\dagger$\normalfont}{\end{Exc}}
\Newassociation{sol}{Solution}{answers}
\renewcommand{\Solutionlabel}[1]{\null}% suppresses the label

At the start of the document:

\begin{document}
\Opensolutionfile{answers}[exanswers]


In the text:

1. An exercise without a solution:

\begin{ex} Show that
$f(A_1\cup A_2)= f(A_1)\cup f(A_2)$.
\end{ex}

  -- This will set the exercise with a label like

1.2.3.1 Exercise Show that ...

where 1.2.3 is the subsection number, and this is the first exercise in that subsection. The "1.2.3.1 Exercise" will be in bold, and the rest in the ambient normalfont of the document.

2. An exercise with a solution:

\begin{exw} Write out the proofs of all the
remaining identities in the Proposition.
\end{exw}
\begin{sol}
Hint: Imitate the proof given for the first one.
\end{sol}

 -- This will set the exercise with a label like

1.2.3.2 Exercise $dagger$ Write out ...

where 1.2.3 is the subsection number and this is the second exercise in it.  $dagger$ will print as a dagger, flagging the fact that there is a solution given later.  The 1.2.3.2 and the material in the sol environment will be enclosed in a Solution environment and written out to the file exanswers.tex.

Finally, at the point where answers are to appear in the appendix:

\Closesolutionfile{answers}
\input{exanswers.tex}