Disallowed emulated drives for superuser, allowed stdio:/dev/null for all
This commit is contained in:
parent
e54f3adc0e
commit
1024e2a68d
@ -347,6 +347,9 @@ permissions.
|
||||
Addresses of emulated drives begin with prefix "stdio:". E.g.
|
||||
dev=stdio:/tmp/my_pseudo_drive
|
||||
|
||||
For safety reasons the superuser is only allowed to use /dev/null as emulated
|
||||
drive. See man page section FILES for a way to lift that ban.
|
||||
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
|
@ -31,7 +31,7 @@ via libburn.
|
||||
\fBcdrskin\fP is a program that provides some of cdrecord's options
|
||||
in a compatible way for CD media. With DVD it has its own ways.
|
||||
You do not need to be superuser for its daily usage.
|
||||
.PP
|
||||
.SS
|
||||
.B Overview of features:
|
||||
.br
|
||||
Blanking of CD-RW and DVD-RW.
|
||||
@ -57,7 +57,7 @@ or on data file or block device.
|
||||
Bus scan, burnfree, speed options, retrieving media info, padding, fifo.
|
||||
.br
|
||||
See section EXAMPLES at the end of this text.
|
||||
.PP
|
||||
.SS
|
||||
.B General information paragraphs:
|
||||
.br
|
||||
Track recording model
|
||||
@ -71,7 +71,9 @@ Sequentially Recordable DVD Media
|
||||
Overwriteable DVD Media
|
||||
.br
|
||||
Drive preparation and addressing
|
||||
.PP
|
||||
.br
|
||||
Emulated drives
|
||||
.SS
|
||||
.B Track recording model:
|
||||
.br
|
||||
The input-output entities which get processed are called tracks.
|
||||
@ -113,7 +115,7 @@ Another type of data track content are archive formats which originally
|
||||
have been developed for magnetic tapes. Only formats which mark a detectable
|
||||
end-of-archive in their data are suitable, though. Well tested are
|
||||
the archivers afio and star. Not suitable seems GNU tar.
|
||||
.PP
|
||||
.SS
|
||||
.B Write mode selection:
|
||||
.br
|
||||
In general there are two approaches for writing media:
|
||||
@ -136,7 +138,7 @@ the capabilities of the drive and the state of the present media.
|
||||
So the mentioning of write modes in the following paragraphs and in the
|
||||
examples is not so much a demand that the user shall choose one explicitely,
|
||||
but rather an illustration of what to expect with particular media types.
|
||||
.PP
|
||||
.SS
|
||||
.B Recordable CD Media:
|
||||
.br
|
||||
CD-R can be initially written only once and eventually extended until they
|
||||
@ -158,7 +160,7 @@ is the appropriate option.
|
||||
Blanking damages the previous content but does not
|
||||
make it completely unreadable. It is no effective privacy precaution.
|
||||
Multiple cycles of blanking and overwriting with random numbers might be.
|
||||
.PP
|
||||
.SS
|
||||
.B Sequentially Recordable DVD Media:
|
||||
.br
|
||||
Currently DVD-RW, DVD-R and DVD+R can be used for the Sequential recording
|
||||
@ -208,7 +210,7 @@ allows appendable media.
|
||||
Option -multi might make DVD media unreadable in some DVD-ROM drives.
|
||||
Best reader compatibility is achieved without it
|
||||
(i.e. by single session media).
|
||||
.PP
|
||||
.SS
|
||||
.B Overwriteable DVD Media:
|
||||
.br
|
||||
Currently types DVD+RW, DVD-RW and DVD-RAM can be overwritten via cdrskin.
|
||||
@ -237,7 +239,7 @@ can be done by option
|
||||
Several programs like dvd+rw-format, cdrecord, wodim, or cdrskin
|
||||
can bring a DVD-RW out of overwriteable state so
|
||||
that it has to be formatted again. If in doubt, just give it a try.
|
||||
.PP
|
||||
.SS
|
||||
.B Drive preparation and addressing:
|
||||
.br
|
||||
The drives, either CD burners or DVD burners, are accessed via addresses which
|
||||
@ -273,7 +275,9 @@ Further are accepted on Linux: links to libburn-suitable device files,
|
||||
device files which have the same major and minor device number,
|
||||
and device files which have the same SCSI address parameters (e.g. /dev/sg0).
|
||||
.br
|
||||
.PP
|
||||
.SS
|
||||
.B Emulated drives:
|
||||
.br
|
||||
Option --allow_emulated_drives enables addressing of pseudo-drives
|
||||
which get emulated on top of filesystem objects. Regular data files and
|
||||
block devices result in pseudo-drives which behave much like DVD-RAM.
|
||||
@ -285,12 +289,6 @@ The target file address is given after prefix "stdio:".
|
||||
.br
|
||||
E.g.: dev=stdio:/tmp/my_pseudo_drive
|
||||
.br
|
||||
Note: --allow_emulated_drives will not work if cdrskin has changed user
|
||||
identity via the setuid bit of its access permissions.
|
||||
.br
|
||||
Warning: Superusers must take care not to spoil their hard disk via its raw
|
||||
block device (like /dev/hda or /dev/sd0).
|
||||
.br
|
||||
Addresses of the form "stdio:/dev/fd/<number>" are treated special. The
|
||||
number is read literally and used as open file descriptor. With
|
||||
dev="stdio:/dev/fd/1" the normal standard output of the program is
|
||||
@ -299,7 +297,15 @@ redirected to stderr and the stream data of a burn run will appear on stdout.
|
||||
Not good for terminals ! Redirect it.
|
||||
.br
|
||||
Pseudo-drives allow -dummy. Their reply with --tell_media_space can be utopic.
|
||||
Note: -dummy burn runs touch the file but do not modify its data content.
|
||||
-dummy burn runs touch the file but do not modify its data content.
|
||||
.br
|
||||
Note: --allow_emulated_drives is restricted to stdio:/dev/null if cdrskin
|
||||
is run by the
|
||||
.B superuser
|
||||
or if it has changed user identity via the
|
||||
.B setuid
|
||||
bit of its access permissions. The ban for the superuser can be lifted by a
|
||||
skillfully created file. See section FILES below.
|
||||
.br
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
@ -1154,6 +1160,9 @@ cdrskin -v dev=ATA:1,0,0 speed=48 -sao \\
|
||||
track1.wav track2.au -audio -swab track3.raw
|
||||
.br
|
||||
.SH FILES
|
||||
.SS
|
||||
Startup files:
|
||||
.br
|
||||
If not --no_rc is given as the first argument then cdrskin attempts on
|
||||
startup to read the arguments from the following files:
|
||||
.PP
|
||||
@ -1171,23 +1180,32 @@ The files are read in the sequence given above, but none of them is
|
||||
required for cdrskin to function properly. Each readable line is treated
|
||||
as one single argument. No extra blanks.
|
||||
A first character '#' marks a comment, empty lines are ignored.
|
||||
.SS
|
||||
.B Example content of a startup file:
|
||||
.br
|
||||
Example content of a startup file:
|
||||
.br
|
||||
# This is the default device
|
||||
.br
|
||||
dev=0,1,0
|
||||
.br
|
||||
# To accomodate to remnant cdrskin-0.2.2 addresses
|
||||
.br
|
||||
dev_translation=+1,0,0+0,1,0
|
||||
.br
|
||||
# Some more options
|
||||
.br
|
||||
fifo_start_at=0
|
||||
.br
|
||||
fs=16m
|
||||
.br
|
||||
.SS
|
||||
Disabling superuser safety precautions:
|
||||
The superuser is normally banned from using any other emulated drive but
|
||||
/dev/null. This ban can be lifted by the existence of file
|
||||
.PP
|
||||
.B /root/cdrskin_permissions/allow_emulated_drives
|
||||
.PP
|
||||
where the directory must be owned by the superuser and must not offer
|
||||
w-permissions for group or others.
|
||||
.br
|
||||
Warning: Superusers must take care not to spoil their hard disk via its raw
|
||||
block device (like stdio:/dev/hda or stdio:/dev/sd0).
|
||||
|
||||
.SH SEE ALSO
|
||||
.TP
|
||||
Formatting data track sources for cdrskin:
|
||||
|
@ -845,10 +845,10 @@ struct CdrtracK {
|
||||
/** Eventually detected data image size */
|
||||
double data_image_size;
|
||||
char *iso_fs_descr; /* eventually block 16 to 31 of input during detection */
|
||||
/** Wether to demand a detected data image size and use it (or else abort) */
|
||||
/** Whether to demand a detected data image size and use it (or else abort) */
|
||||
int use_data_image_size; /* 0=no, 1=size not defined yet, 2=size defined */
|
||||
|
||||
/* wether the data source is a container of defined size with possible tail */
|
||||
/* Whether the data source is a container of defined size with possible tail*/
|
||||
int extracting_container;
|
||||
|
||||
/** Optional fifo between input fd and libburn. It uses a pipe(2) to transfer
|
||||
@ -1056,7 +1056,7 @@ int Cdrtrack_get_fifo(struct CdrtracK *track, struct CdrfifO **fifo, int flag)
|
||||
}
|
||||
|
||||
|
||||
/** Try wether automatic audio extraction is appropriate and eventually open
|
||||
/** Try whether automatic audio extraction is appropriate and eventually open
|
||||
a file descriptor to the raw data.
|
||||
@return -3 identified as .wav but with cdrecord-inappropriate parameters
|
||||
-2 could not open track source, no use in retrying
|
||||
@ -1661,7 +1661,7 @@ struct CdrpreskiN {
|
||||
char queue_severity[81];
|
||||
char print_severity[81];
|
||||
|
||||
/** Wether to wait for available standard input data before touching drives */
|
||||
/** Whether to wait for available standard input data before touching drives*/
|
||||
int do_waiti;
|
||||
|
||||
/** Stores eventually given absolute device address before translation */
|
||||
@ -1686,41 +1686,44 @@ struct CdrpreskiN {
|
||||
*/
|
||||
int abort_handler;
|
||||
|
||||
/** Wether to allow getuid()!=geteuid() */
|
||||
/** Whether to allow getuid()!=geteuid() */
|
||||
int allow_setuid;
|
||||
|
||||
/** Wether to allow user provided addresses like #4 */
|
||||
/** Whether to allow user provided addresses like #4 */
|
||||
int allow_fd_source;
|
||||
|
||||
/** Wether to support media types which are implemented but yet untested */
|
||||
/** Whether to support media types which are implemented but yet untested */
|
||||
int allow_untested_media;
|
||||
|
||||
/** Wether to allow libburn pseudo-drives "stdio:<path>" */
|
||||
/** Whether to allow libburn pseudo-drives "stdio:<path>" .
|
||||
0=forbidden, 1=seems ok,
|
||||
2=potentially forbidden (depends on uid, euid, file type)
|
||||
*/
|
||||
int allow_emulated_drives;
|
||||
|
||||
/** Wether an option is given which needs a full bus scan */
|
||||
/** Whether an option is given which needs a full bus scan */
|
||||
int no_whitelist;
|
||||
|
||||
/** Wether the translated device address shall not follow softlinks, device
|
||||
/** Whether the translated device address shall not follow softlinks, device
|
||||
clones and SCSI addresses */
|
||||
int no_convert_fs_adr;
|
||||
|
||||
/** Wether Bus,Target,Lun addresses shall be converted literally as old
|
||||
/** Whether Bus,Target,Lun addresses shall be converted literally as old
|
||||
Pseudo SCSI-Adresses. New default is to use (possibly system emulated)
|
||||
real SCSI addresses via burn_drive_convert_scsi_adr() and literally
|
||||
emulated and cdrecord-incompatible ATA: addresses. */
|
||||
int old_pseudo_scsi_adr;
|
||||
|
||||
/** Wether bus scans shall exit!=0 if no drive was found */
|
||||
/** Whether bus scans shall exit!=0 if no drive was found */
|
||||
int scan_demands_drive;
|
||||
|
||||
/** Wether to abort when a busy drive is encountered during bus scan */
|
||||
/** Whether to abort when a busy drive is encountered during bus scan */
|
||||
int abort_on_busy_drive;
|
||||
|
||||
/** Linux specific : Wether to try to avoid collisions when opening drives */
|
||||
/** Linux specific : Whether to try to avoid collisions when opening drives */
|
||||
int drive_exclusive;
|
||||
|
||||
/** Linux specific : Wether to obtain an exclusive drive lock via fcntl() */
|
||||
/** Linux specific : Whether to obtain an exclusive drive lock via fcntl() */
|
||||
int drive_fcntl_f_setlk;
|
||||
|
||||
/** Linux specific : Device file address family to use :
|
||||
@ -1728,7 +1731,7 @@ struct CdrpreskiN {
|
||||
int drive_scsi_dev_family;
|
||||
|
||||
|
||||
/** Wether to try to wait for unwilling drives to become willing to open */
|
||||
/** Whether to try to wait for unwilling drives to become willing to open */
|
||||
int drive_blocking;
|
||||
|
||||
/** Explicit write mode option is determined before skin processes
|
||||
@ -1946,6 +1949,52 @@ int Cdrpreskin_queue_msgs(struct CdrpreskiN *o, int flag)
|
||||
}
|
||||
|
||||
|
||||
/** Evaluate whether the user would be allowed in any case to use device_adr
|
||||
as pseudo-drive */
|
||||
int Cdrpreskin__allows_emulated_drives(char *device_adr, char reason[4096],
|
||||
int flag)
|
||||
{
|
||||
struct stat stbuf;
|
||||
|
||||
reason[0]= 0;
|
||||
if(device_adr[0]) {
|
||||
if(strcmp(device_adr,"/dev/null")==0)
|
||||
return(1);
|
||||
strcat(reason,"File object is not /dev/null. ");
|
||||
}
|
||||
|
||||
if(getuid()!=geteuid()) {
|
||||
strcat(reason,"UID and EUID differ");
|
||||
return(0);
|
||||
}
|
||||
if(getuid()!=0)
|
||||
return(1);
|
||||
|
||||
strcat(reason,"UID is 0. ");
|
||||
/* Directory must be owned by root and write protected against any others*/
|
||||
if(lstat("/root/cdrskin_permissions",&stbuf)==-1 || !S_ISDIR(stbuf.st_mode)) {
|
||||
strcat(reason, "No directory /root/cdrskin_permissions exists");
|
||||
return(0);
|
||||
}
|
||||
if(stbuf.st_uid!=0) {
|
||||
strcat(reason, "Directory /root/cdrskin_permissions not owned by UID 0");
|
||||
return(0);
|
||||
}
|
||||
if(stbuf.st_mode & (S_IWGRP | S_IWOTH)) {
|
||||
strcat(reason,
|
||||
"Directory /root/cdrskin_permissions has w-permission for group or others");
|
||||
return(0);
|
||||
}
|
||||
if(stat("/root/cdrskin_permissions/allow_emulated_drives",&stbuf)==-1) {
|
||||
strcat(reason,
|
||||
"No file /root/cdrskin_permissions/allow_emulated_drives exists");
|
||||
return(0);
|
||||
}
|
||||
reason[0]= 0;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int Cdrpreskin_consider_normal_user(int flag)
|
||||
{
|
||||
fprintf(stderr,
|
||||
@ -2177,7 +2226,7 @@ return:
|
||||
*/
|
||||
{
|
||||
int i,ret;
|
||||
char *value_pt;
|
||||
char *value_pt, reason[4096];
|
||||
|
||||
#ifndef Cdrskin_extra_leaN
|
||||
if(argc>1) {
|
||||
@ -2220,10 +2269,12 @@ return:
|
||||
o->abort_handler= 3;
|
||||
|
||||
} else if(strcmp(argv[i],"--allow_emulated_drives")==0) {
|
||||
if(getuid()!=geteuid()) {
|
||||
if(Cdrpreskin__allows_emulated_drives("",reason,0)<=0) {
|
||||
fprintf(stderr,"cdrskin: WARNING : %s.\n",reason);
|
||||
fprintf(stderr,
|
||||
"cdrskin: SORRY : uid and euid differ. Will not --allow_emulated_drives\n");
|
||||
"cdrskin: WARNING : Only /dev/null will be available with \"stdio:\".\n");
|
||||
Cdrpreskin_consider_normal_user(0);
|
||||
o->allow_emulated_drives= 2;
|
||||
} else
|
||||
o->allow_emulated_drives= 1;
|
||||
|
||||
@ -2360,15 +2411,18 @@ set_dev:;
|
||||
}
|
||||
if(o->allow_emulated_drives) {
|
||||
fprintf(stderr,"\nTransport name:\t\tlibburn on standard i/o\n");
|
||||
fprintf(stderr,
|
||||
"Transport descr.:\twrite into data files and block devices\n");
|
||||
if(o->allow_emulated_drives==2)
|
||||
fprintf(stderr, "Transport descr.:\troot or setuid may only write into /dev/null\n");
|
||||
else
|
||||
fprintf(stderr, "Transport descr.:\twrite into file objects\n");
|
||||
fprintf(stderr,"Transp. layer ind.:\tstdio:\n");
|
||||
fprintf(stderr,"Target specifier:\tpath\n");
|
||||
fprintf(stderr,"Target example:\t\tstdio:/tmp/pseudo_drive\n");
|
||||
fprintf(stderr,"SCSI Bus scanning:\tnot supported\n");
|
||||
fprintf(stderr,"Open via UNIX device:\tsupported\n");
|
||||
} else {
|
||||
printf("\ncdrskin: NOTE : Option --allow_emulated_drives would allow dev=stdio:<path>\n");
|
||||
if(Cdrpreskin__allows_emulated_drives("",reason,0)>0)
|
||||
printf("\ncdrskin: NOTE : Option --allow_emulated_drives would allow dev=stdio:<path>\n");
|
||||
}
|
||||
|
||||
#else /* ! Cdrskin_extra_leaN */
|
||||
@ -2450,8 +2504,7 @@ set_dev:;
|
||||
printf(
|
||||
" --adjust_speed_to_drive set only speeds offered by drive and media\n");
|
||||
#endif
|
||||
printf(
|
||||
" --allow_emulated_drives dev=stdio:<path> on files and block devices\n");
|
||||
printf(" --allow_emulated_drives dev=stdio:<path> on file objects\n");
|
||||
printf(
|
||||
" --allow_setuid disable setuid warning (setuid is insecure !)\n");
|
||||
printf(
|
||||
@ -3031,7 +3084,7 @@ struct CdrskiN {
|
||||
char device_adr[Cdrskin_adrleN];
|
||||
|
||||
|
||||
/** Progress state info: wether libburn is actually processing payload data */
|
||||
/** Progress state info: whether libburn is actually processing payload data*/
|
||||
int is_writing;
|
||||
/** Previously detected drive state */
|
||||
enum burn_drive_status previous_drive_status;
|
||||
@ -3043,7 +3096,7 @@ struct CdrskiN {
|
||||
int lib_is_initialized;
|
||||
pid_t control_pid; /* pid of the thread that calls libburn */
|
||||
int drive_is_grabbed;
|
||||
int drive_is_busy; /* Wether drive was told to do something cancel-worthy */
|
||||
int drive_is_busy; /* Whether drive was told to do something cancel-worthy */
|
||||
struct burn_drive *grabbed_drive;
|
||||
|
||||
#ifndef Cdrskin_extra_leaN
|
||||
@ -3981,7 +4034,7 @@ adr_translation:;
|
||||
/* user defined address translation */
|
||||
if(!(flag&1)) {
|
||||
if(ret>0) {
|
||||
/* try wether a translation points to loc */
|
||||
/* try whether a translation points to loc */
|
||||
hret= Cdradrtrn_translate(skin->adr_trn,loc,driveno,buf,1);
|
||||
if(hret==2) {
|
||||
still_untranslated= 0;
|
||||
@ -5292,7 +5345,7 @@ ex:;
|
||||
#ifdef Cdrskin_libburn_write_mode_ruleS
|
||||
|
||||
/** After everything else about burn_write_opts and burn_disc is set up, this
|
||||
call determines the effective write mode and checks wether the drive
|
||||
call determines the effective write mode and checks whether the drive
|
||||
promises to support it.
|
||||
*/
|
||||
int Cdrskin_activate_write_mode(struct CdrskiN *skin,
|
||||
@ -5367,7 +5420,7 @@ report_failure:;
|
||||
|
||||
#else /* Cdrskin_libburn_write_mode_ruleS */
|
||||
|
||||
/** Determines the effective write mode and checks wether the drive promises
|
||||
/** Determines the effective write mode and checks whether the drive promises
|
||||
to support it.
|
||||
@param s state of target media, obtained from burn_disc_get_status(),
|
||||
submit BURN_DISC_BLANK if no real state is available
|
||||
@ -5473,7 +5526,7 @@ int Cdrskin_activate_write_mode(struct CdrskiN *skin, enum burn_disc_status s,
|
||||
skin->block_type= BURN_BLOCK_SAO;
|
||||
}
|
||||
|
||||
/* check wether desired type combination is available with drive */
|
||||
/* check whether desired type combination is available with drive */
|
||||
if(skin->driveno<0 || skin->driveno>skin->n_drives) {
|
||||
if(skin->verbosity>=Cdrskin_verbose_debuG)
|
||||
ClN(printf("cdrskin_debug: WARNING : No drive selected with Cdrskin_activate_write_mode\n"));
|
||||
@ -7518,7 +7571,7 @@ ignore_unknown:;
|
||||
/** Initialize libburn, create a CdrskiN program run control object,
|
||||
set eventual device whitelist, and obtain the list of available drives.
|
||||
@param o Returns the CdrskiN object created
|
||||
@param lib_initialized Returns wether libburn was initialized here
|
||||
@param lib_initialized Returns whether libburn was initialized here
|
||||
@param exit_value Returns after error the proposal for an exit value
|
||||
@param flag Unused yet
|
||||
@return <=0 error, 1 success
|
||||
@ -7528,6 +7581,7 @@ int Cdrskin_create(struct CdrskiN **o, struct CdrpreskiN **preskin,
|
||||
{
|
||||
int ret, stdio_drive= 0;
|
||||
struct CdrskiN *skin;
|
||||
char reason[4096];
|
||||
|
||||
*o= NULL;
|
||||
*exit_value= 0;
|
||||
@ -7538,15 +7592,23 @@ int Cdrskin_create(struct CdrskiN **o, struct CdrpreskiN **preskin,
|
||||
(*preskin)->device_adr));
|
||||
burn_drive_add_whitelist((*preskin)->device_adr);
|
||||
if(strncmp((*preskin)->device_adr, "stdio:", 6)==0) {
|
||||
if((*preskin)->allow_emulated_drives) {
|
||||
ret= Cdrpreskin__allows_emulated_drives((*preskin)->device_adr+6,reason,0);
|
||||
if((*preskin)->allow_emulated_drives && ret>0) {
|
||||
stdio_drive= 1;
|
||||
(*preskin)->demands_cdrskin_caps= 1;
|
||||
} else if((*preskin)->allow_emulated_drives) {
|
||||
fprintf(stderr,"cdrskin: SORRY : dev=stdio:... rejected despite --allow_emulated_drives\n");
|
||||
fprintf(stderr,"cdrskin: SORRY : Reason: %s.\n", reason);
|
||||
} else {
|
||||
fprintf(stderr,"cdrskin: SORRY : dev=stdio:... works only with option --allow_emulated_drives\n");
|
||||
if(getuid()!=geteuid()) {
|
||||
fprintf(stderr,"cdrskin: SORRY : but uid and euid differ. So this option will be rejected.\n");
|
||||
Cdrpreskin_consider_normal_user(0);
|
||||
if(ret<=0) {
|
||||
fprintf(stderr,"cdrskin: SORRY : but: %s.\n", reason);
|
||||
fprintf(stderr,
|
||||
"cdrskin: SORRY : So this option would not help anyway.\n");
|
||||
}
|
||||
}
|
||||
if(!stdio_drive) {
|
||||
Cdrpreskin_consider_normal_user(0);
|
||||
{*exit_value= 2; goto ex;}
|
||||
}
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
#define Cdrskin_timestamP "2007.09.26.173840"
|
||||
#define Cdrskin_timestamP "2007.09.27.083351"
|
||||
|
@ -54,9 +54,10 @@ then
|
||||
-e 's/^The write modes for DVD+R/\ <BR>The write modes for DVD+R/' \
|
||||
-e 's/<b>Drive preparation and addressing:<\/b>/\ <BR><b>Drive preparation and addressing:<\/b>/' \
|
||||
-e 's/^If you only got one CD capable drive/\ <BR>If you only got one CD capable drive/' \
|
||||
-e 's/^Option --allow_emulated_drives enables/\ <BR>Option --allow_emulated_drives enables/' \
|
||||
-e 's/<b>Emulated drives:<\/b>/\ <BR><b>Emulated drives:<\/b>/' \
|
||||
-e 's/^Alphabetical list of options/\ <BR>Alphabetical list of options/' \
|
||||
-e 's/and for all others\.<\/td><\/table>/and for all others.<\/td><\/table> <BR><HR><FONT SIZE=-1><CENTER>(HTML generated from '"$manpage"'.1 on '"$(date)"' by '$(basename "$0")' )<\/CENTER><\/FONT>/' \
|
||||
-e 's/See section FILES/See section <A HREF="#FILES">FILES<\/A>/' \
|
||||
-e 's/See section EXAMPLES/See section <A HREF="#EXAMPLES">EXAMPLES<\/A>/' \
|
||||
<"$2" >"$htmlpage"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user