Questions and Answers
Amy Rich
Q I've written a bunch of scripts in PHP that I recently tried to migrate from a machine running 4.2 to a machine running 5.2. When I run the scripts, I get all sorts of errors. A simple test script which illustrates the problems I'm having is:
#!/usr/bin/php -q /* -*- c -*- */
<?php
print("Hello, world.\n");
?>
Under PHP 4.2, this told the interpreter to ignore everything after the -q, and the output was simply Hello, world..
Under PHP 5.2, I get the PHP usage statement:
Usage: php [options] [-f] <file> [--] [args...]
php [options] -r <code> [--] [args...]
php [options] [-B <begin_code>] -R <code> [-E <end_code>] \
[--] [args...]
php [options] [-B <begin_code>] -F <file> [-E <end_code>] \
[--] [args...]
php [options] -- [args...]
php [options] -a
-a Run interactively
-c <path>|<file> Look for php.ini file in this directory
-n No php.ini file will be used
-d foo[=bar] Define INI entry foo with value 'bar'
-e Generate extended information for debugger/profiler
-f <file> Parse and execute <file>.
-h This help
-i PHP information
-l Syntax check only (lint)
-m Show compiled in modules
-r <code> Run PHP <code> without using script tags <?..?>
-B <begin_code> Run PHP <begin_code> before processing input lines
-R <code> Run PHP <code> for every input line
-F <file> Parse and execute <file> for every input line
-E <end_code> Run PHP <end_code> after processing all input lines
-H Hide any passed arguments from external tools.
-s Display colour syntax highlighted source.
-v Version number
-w Display source with stripped comments and whitespace.
-z <file> Load Zend extension <file>.
args... Arguments passed to script. Use -- args when first
argument starts with - or script is read from stdin
--rf <name> Show information about function <name>.
--rc <name> Show information about class <name>.
--re <name> Show information about extension <name>.
There's obviously an issue with the syntax because there's no -q listed as a command-line argument anymore. I took out the -q, but running the script only resulted in the error:
Could not open input file: /* -*- c -*- */
I'd really like to keep the /* -*- c -*- */ part in the first line because that sets the mode to C for me in emacs. Is there any way around this?
A Your problem is that the PHP interpreter is expanding your comment line as arguments to PHP itself. This is documented in the PHP manual at:
http://us.php.net/features.commandline
As long as the arguments you want to pass to your script do not start with the - character, there's nothing special to watch out for. Passing an argument to your script which starts with a - will cause trouble because PHP itself thinks it has to handle it. To prevent this, use the argument list separator --. After this separator has been parsed by PHP, every argument following it is passed untouched to your script.
So your shebang line for any scripts that you port to 5.2 should look like the following instead:
#!/usr/bin/php -- /* -*- c -*- */
Q We're running Solaris 10 on a number of servers we'd like to decommission. To do so securely, we'd like to wipe the disks of any information. Is there something built into Solaris that will do this for us, or are there any good third-party tools that we could use? Also, how do you get around wiping the disk while it's still in the system? Do you run a utility from the OBP or from a CD-ROM? The latter would be an issue for us, because not all of our machines have CD-ROM drives. Thanks for any help you can provide.
A The people who work on OpenSolaris have been discussing secure wipe, but as far as I know, nothing that completely wipes an entire disk has been implemented yet. My approach has always been to use the BCWipe tool from Jetico:
http://www.jetico.com/index.htm#/bcwipe_unix.htm
This tool will completely wipe a disk on a Unix machine. It will securely delete files and directories as well.
Instead of making a bootable CD (which you can certainly do), I've always patched my jumpstart boot server to include the bcwipe package. To do so:
1. Download the latest source code tar ball of BCWipe from:
http://www.jetico.com/index.htm#/linux/
2. Compile the software and turn it into a Solaris package that will install into /sbin.
3. Patch the jumpstart boot environment with the new package. The example command below assumes that the package is called bcwipe and is in the current working directory in directory format. It also assumes that your jumpstart install image is located at /inst/media/Solaris_10/Solaris_10/Tools/Boot:
pkgadd -R /inst/media/Solaris_10/Solaris_10/Tools/Boot -d `pwd` bcwipe
Then, when you need to wipe a boot disk, boot into single-user mode over the network from the image on the jumpstart server (generally with the command boot net -s or boot net:dhcp -s from the client machine's ok prompt) and run bcwipe from the network booted mini-root.
You can choose how paranoid you'd like to be when you supply options to bcwipe because there are several wiping algorithms you can use. Wiping options include:
-md -- U.S. DoD 5200.28 seven pass extended character rotation wiping.
-m <mode> -- U.S. DoD 5200.28 n pass extended character rotation wiping.
-mg -- 35-pass Peter Gutmann's wiping.
-mz -- One pass zero wiping.
-mt -- One pass test mode. The first 4 bytes of every 512 bytes block
will contain block number.
In normal mode, 35 passes (8 random) are used to overwrite data per Peter Gutmann's article titled "Secure Deletion of Data from Magnetic and Solid-State Memory":
http://www.cs.auckland.ac.nz/~pgut001/pubs/secure_del.html
This is generally overkill, so you might want to go with something lighter like the 7-pass rotation wiping, one-pass zeroing, or some custom number of passes.
Additionally, if you are wiping a cache-backed storage array, use the -n flag to delay between wiping passes:
-n <delay>
Wait delay seconds between wiping passes. Modern enterprise level
storage systems (NAS, disk arrays etc.) employ powerful caches. To
avoid undesirable caching effects BCWipe allows user to insert
adjustable delay between wiping passes. Please note that when wiping
with delay between passes disk space is freed after the last pass.
To perform a one-pass zeroing of the slice /dev/dsk/c0t0d0s0, you'd run:
/sbin/bcwipe -bmz /dev/rdsk/c0t0d0s0
If you have slice 2 set as the entire disk, you can instead wipe the whole disk at once by specifying /dev/rdsk/c0t0d0s2 instead of /dev/rdsk/c0t0d0s0.
Q I'm running FreeBSD 6.2, and I just upgraded sendmail to 8.14.1. After the upgrade I'm no longer seeing the envelope from in the Received: header. A bunch of stuff has changed, so there's a lot that I don't understand when diffing the config files. I didn't see anything obvious in the FAQ, INSTALL, KNOWNBUGS, README, or RELEASE_NOTES files that would explain the change in behavior. Do you know what I'm missing?
A The sendmail that comes with FreeBSD 6.2 has been modified from the sendmail.org version to include this additional information. When you upgraded to the sendmail.org version, you lost this customization. Take a look at the CVS version of src/contrib/sendmail/cf/m4/cfhead.m4 from the FreeBSD Web site:
http://www.freebsd.org/cgi/cvsweb.cgi/src/contrib/sendmail/cf/ \
m4/cfhead.m4?rev=1.3.6.11
Specifically, there's a block of define lines that deal with the Received: headers:
define(`_REC_AUTH_`, `$.$?{auth_type}(authenticated')
define(`_REC_FULL_AUTH_', `$.$?{auth_type}(user=${auth_authen}
$?{auth_author}author=${auth_author} $.mech=${auth_type}')
define(`_REC_HDR_', `$?sfrom $s $.$?_($?s$|from $.$_)')
define(`_REC_END_', `for $u; $|;
$.$b$?g
(envelope-from $g)$.')
define(`_REC_TLS_', `(version=${tls_version} cipher=${cipher}
bits=${cipher_bits} verify=${verify})$.$?u')
define(`_REC_BY_', `$.by $j ($v/$Z)$?r with $r$. id $i$?{tls_version}')
define(`confRECEIVED_HEADER', `_REC_HDR_
_REC_AUTH_$?{auth_ssf} bits=${auth_ssf}$.)
_REC_BY_
_REC_TLS_
_REC_END_')
The envelope from is added as part of _REC_END_ line above. You can always add this functionality back in by overriding the _REC_END_ definition in your devtools/Site/site.config.m4 file.
Q I have six files that I need to merge together, interleaving the lines from each file. The files contain a date, number, first name, last name, number, and random string. The output must not be sorted, but must appear in the exact same order as the input files. Here are some sample input files and an output file to help illustrate my requirements:
file 1: file 4:
12/01/2006 Doe
11/02/2006 Doe
01/03/2007 Smith
09/13/2005 Johnson
file 2: file 5:
230982 1132
0985231 1133
8134776 1134
9561573 1135
file 3: file 6:
John contacted
Jane new
Joe closed
Sally stalled
What I need to wind up with is one file that looks like:
12/01/2006
230982
John
Doe
1132
contacted
11/02/2006
0985231
Jane
Doe
1133
new
01/03/2007
8134776
Joe
Smith
1134
closed
09/13/2005
9561573
Sally
Johnson
1135
stalled
Most of the solutions I've thought of wind up sorting the data in some way and taking it out of order. Can you write a script that will do what I need?
A Assuming that each of your six files has the same number of records, you can easily fold them together as you describe with the paste command:
paste -d'\n' file1 file2 file3 file4 file5 file6 > output
If you don't have the same number of records in every file, then you'll be left with blank lines in the output file, e.g.:
file1: file2: output of paste -d'\n' file1 file2:
a 1 a
b 2 1
c 3 b
4 2
c
3
4
You can remove these blank lines using your favorite utility (sed, grep, etc.) if they are undesirable:
paste -d'\n' file1 file2 |grep -v ^$ > output
You will need to escape the $ if you're not using a Bourne-derived shell to prevent attempted variable expansion.
Amy Rich has more than a decade of Unix systems administration experience in various types of environments. Her current roles include that of Senior Systems Administrator for the University Systems Group at Tufts University, Unix systems administration consultant, author, and charter member of LOPSA. She can be reached at: qna@oceanwave.com.
|