Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/perl
- # FILE: ovcbin/ovcext.pm 755
- # ovcbin/ovcext.pm -- ovrcat archive extractor
- #
- # this is a self extracting archive
- # after the __DATA__ line, files are separated by:
- # % filename
- # ovcext_cmd -- extract archive
- ovcext_cmd(@ARGV);
- exit(0);
- sub ovcext_cmd
- {
- my(@argv) = @_;
- local($xfdata);
- local($xfdiv,$divcur,%ovcdiv_lookup);
- $pgmtail = "ovcext";
- ovcinit();
- ovcopt(\@argv,qw(opt_go opt_f opt_t));
- $xfdata = "ovrcat::DATA";
- $xfdata = \*$xfdata;
- # first line is options
- ovceval($xfdata);
- # data area is compressed
- ovcfifo($zipflg_all);
- # process all lines
- ovcline($xfdata);
- $code = ovcwait();
- ovcclose(\$xfdata);
- # close output units
- ovcdiv();
- # decode base64 and decompress
- ovczipd_spl()
- if ($zipflg_spl);
- }
- # ovceval -- decode options line
- sub ovceval
- {
- my($xfdata) = @_;
- my($buf,$err);
- {
- $buf = <$xfdata>;
- chomp($buf);
- # FORMAT:
- # $foo = 1;
- # @foo = (1,2);
- last unless ($buf =~ s/^%\s+([\@\$;])/$1/);
- eval($buf);
- # normal -- no error
- $err = $@;
- unless ($err) {
- undef($buf);
- last;
- }
- chomp($err);
- $err = " (" . $err . ")"
- }
- sysfault("ovceval: bad options line -- '%s'%s\n",$buf,$err)
- if (defined($buf));
- }
- # ovcline -- normal line
- sub ovcline
- {
- my($xfdata) = @_;
- my($buf);
- my($tail);
- while ($buf = <$xfdata>) {
- chomp($buf);
- if ($buf =~ /^%\s+(.+)$/) {
- $tail = $1;
- ovcdiv($tail);
- next;
- }
- print($xfdiv $buf,"\n")
- if (ref($xfdiv));
- }
- }
- # ovcdiv -- open output bucket
- sub ovcdiv
- {
- my($ofile) = @_;
- my($mode);
- my($xfcur);
- my($err,$prt);
- ($ofile,$mode) = split(" ",$ofile);
- $mode = oct($mode);
- $mode &= 0777;
- {
- # close all streams
- unless (defined($ofile)) {
- while ((undef,$divcur) = each(%ovcdiv_lookup)) {
- close($divcur->{div_xfdst});
- }
- ###undef(%ovcdiv_lookup);
- last;
- }
- # force all files to be relative to current directory
- $ofile = ovctail($ofile);
- # get already open stream
- $divcur = $ovcdiv_lookup{$ofile};
- if (ref($divcur)) {
- $xfdiv = $divcur->{div_xfdst};
- last;
- }
- undef($xfdiv);
- # now we're lenient
- if (-e $ofile) {
- msg("ovcdiv: file '%s' already exists -- ",$ofile);
- unless ($opt_f) {
- msg("rerun with -f to force\n");
- last;
- }
- msg("overwriting!\n");
- }
- # allow subdirectory
- unless (defined($err)) {
- ovcmkdir($1)
- if ($ofile =~ m,^(.+)/[^/]+$,);
- }
- msg("$pgmtail: %s %s",ovcnogo("extracting"),$ofile);
- msg(" chmod %3.3o",$mode)
- if ($mode);
- msg("\n");
- last unless ($opt_go);
- last if (defined($err));
- $xfcur = ovcopen(">$ofile");
- $divcur = {};
- $ovcdiv_lookup{$ofile} = $divcur;
- if ($mode) {
- chmod($mode,$xfcur);
- $divcur->{div_mode} = $mode;
- }
- $divcur->{div_xfdst} = $xfcur;
- $xfdiv = $xfcur;
- }
- }
- # FILE: ovcbin/ovctiny.pm
- # ovcbin/ovctiny.pm -- common routines
- # ovcinit -- initialize for decompress
- sub ovcinit
- {
- {
- last if (defined($ztmp));
- $ztmp = "/tmp/ovrcat_zip";
- $PWD = $ENV{PWD};
- $quo_2 = '"';
- $ztmp_inp = $ztmp . "_0";
- $ztmp_out = $ztmp . "_1";
- $ztmp_perl = $ztmp . "_perl";
- ovcunlink();
- $ovcdbg = ($ENV{"ZPXHOWOVC"} != 0);
- }
- }
- # ovcunlink -- remove temp files
- sub ovcunlink
- {
- _ovcunlink($ztmp_inp,1);
- _ovcunlink($ztmp_out,1);
- _ovcunlink($ztmp_perl,($pgmtail ne "ovcext") || $opt_go);
- }
- # _ovcunlink -- remove temp file
- sub _ovcunlink
- {
- my($file,$rmflg) = @_;
- my($found,$tag);
- {
- last unless (defined($file));
- $found = (-e $file);
- $tag //= "notfound"
- unless ($found);
- $tag //= $rmflg ? "cleaning" : "keeping";
- msg("ovcunlink: %s %s ...\n",$tag,$file)
- if (($found or $ovcdbg) and (! $ovcunlink_quiet));
- unlink($file)
- if ($rmflg and $found);
- }
- }
- # ovcopt -- decode options (tiny version)
- sub ovcopt
- {
- my($argv) = @_;
- my($opt);
- while (1) {
- $opt = $argv->[0];
- last unless ($opt =~ s/^-/opt_/);
- shift(@$argv);
- $$opt = 1;
- }
- }
- # ovctail -- get tail of file
- sub ovctail
- {
- my($file,$sub) = @_;
- my(@file);
- $file =~ s,^/,,;
- @file = split("/",$file);
- ###$sub //= $opt_t;
- $sub //= 2;
- @file = splice(@file,-$sub)
- if (@file >= $sub);
- $file = join("/",@file);
- $file;
- }
- # ovcmkdir -- make directory
- sub ovcmkdir
- {
- my($odir) = @_;
- my(@lhs,@rhs);
- @rhs = split("/",$odir);
- foreach $rhs (@rhs) {
- push(@lhs,$rhs);
- $odir = join("/",@lhs);
- if ($opt_go) {
- next if (-d $odir);
- }
- else {
- next if ($ovcmkdir{$odir});
- $ovcmkdir{$odir} = 1;
- }
- msg("$pgmtail: %s %s ...\n",ovcnogo("mkdir"),$odir);
- next unless ($opt_go);
- mkdir($odir) or
- sysfault("$pgmtail: unable to mkdir '%s' -- $!\n",$odir);
- }
- }
- # ovcopen -- open file
- sub ovcopen
- {
- my($file,$who) = @_;
- my($xf);
- $who //= $pgmtail;
- $who //= "ovcopen";
- open($xf,$file) or
- sysfault("$who: unable to open '%s' -- $!\n",$file);
- $xf;
- }
- # ovcclose -- close file
- sub ovcclose
- {
- my($xfp) = @_;
- my($ref);
- my($xf);
- {
- $ref = ref($xfp);
- last unless ($ref);
- if ($ref eq "GLOB") {
- close($xfp);
- last;
- }
- if ($ref eq "REF") {
- $xf = $$xfp;
- if (ref($xf) eq "GLOB") {
- close($xf);
- undef($$xfp);
- }
- }
- }
- undef($xf);
- $xf;
- }
- # ovrnogo -- output message
- sub ovcnogo
- {
- my($str) = @_;
- unless ($opt_go) {
- $str = "NOGO-$str";
- $nogo_msg = 1;
- }
- $str;
- }
- # ovcdbg -- debug message
- sub ovcdbg
- {
- if ($ovcdbg) {
- printf(STDERR "[%d] ",$$);
- printf(STDERR @_);
- }
- }
- # msg -- output message
- sub msg
- {
- printf(STDERR @_);
- }
- # msgv -- output message
- sub msgv
- {
- $_ = join(" ",@_);
- print(STDERR $_,"\n");
- }
- # sysfault -- output message and terminate
- sub sysfault
- {
- printf(STDERR @_);
- exit(1);
- }
- # ovcfifo -- dummy version
- sub ovcfifo
- {
- }
- # ovcwait -- wait for fifo to complete
- sub ovcwait
- {
- my($code);
- if ($pid_fifo) {
- waitpid($pid_fifo,0);
- $code = $? >> 8;
- }
- $code;
- }
- # prtstr -- print undefined value without defining it
- sub prtstr
- {
- my($val,$fmtpos,$fmtneg) = @_;
- {
- # print undefined value as undef (without quotes)
- unless (defined($val)) {
- $val = "undef";
- last;
- }
- # print references within parentheses
- if (ref($val)) {
- $val = sprintf("(%s)",$val);
- last;
- }
- # get default format (string)
- $fmtpos //= "'%s'";
- # allow error codes to come out in a different format
- if (defined($fmtneg) && ($val <= 0)) {
- $val = sprintf($fmtneg,$val);
- last;
- }
- # print value using a specific format
- $val = sprintf($fmtpos,$val);
- }
- $val;
- }
- # prtnum -- print base 10 number
- sub prtnum
- {
- my($val) = @_;
- $val = prtstr($val,"%d");
- $val;
- }
- END {
- msg("$pgmtail: rerun with -go to actually do it\n")
- if ($nogo_msg);
- ovcunlink();
- }
- 1;
- package ovrcat;
- __DATA__
- % ;
- % jiffdvr/jiffies.c
- // NOTES:
- // (1) buf is a userspace/logical pointer -- it can't be accessed directly --
- // we must use copy_to_user
- // (2) static variables should be avoided -- we need to allocate a driver
- // private data structure -- so, we need to add .open and .release
- // file operations
- // (3) we must limit our transfer length to the len argument
- // (4) we must honor/update the passed in file offset (loff_t)
- #include <linux/init.h>
- #include <linux/module.h>
- // does not compile too well ...
- #if 0
- #include <asm/uaccess.h>
- #else
- #include <linux/uaccess.h>
- #endif
- #include <linux/fs.h>
- #include <linux/sched.h>
- #include <linux/device.h>
- #include <linux/proc_fs.h>
- #include <linux/string.h>
- #include <linux/timer.h>
- #include <linux/slab.h>
- #define PROC_NAME "jiffies"
- MODULE_LICENSE("GPL 2");
- static int myInit(void);
- static void myExit(void);
- struct proc_dir_entry *my_proc;
- // driver private data
- struct jiffdata {
- size_t len;
- char buf[100];
- };
- #ifdef JIFFDEBUG
- #define dbgprt(_fmt...) \
- printk(_fmt)
- #else
- #define dbgprt(_fmt...) \
- do { } while (0)
- #endif
- static int
- jiff_open(struct inode *ino,struct file *filp)
- {
- struct jiffdata *data;
- // allocate driver private data
- data = kmalloc(GFP_KERNEL,sizeof(struct jiffdata));
- if (data == NULL)
- return -ENOMEM;
- filp->private_data = data;
- return 0;
- }
- static int
- jiff_release(struct inode *ino,struct file *filp)
- {
- struct jiffdata *data = filp->private_data;
- // release driver private data
- if (data != NULL)
- kfree(data->buf);
- return 0;
- }
- /* Read operation on proc */
- static ssize_t
- read_data(struct file *filp, char *buf, size_t len, loff_t *off)
- {
- struct jiffdata *data = filp->private_data;
- loff_t xoff = *off;
- ssize_t retlen;
- int err;
- dbgprt("read_data: ENTER buf=%p len=%lu off=%p xoff=%lld f_pos=%lld\n",
- buf,len,off,xoff,filp->f_pos);
- /* find out current value of jiffies */
- if (xoff == 0) {
- data->len = sprintf(data->buf, "Value of jiffies %lu", jiffies);
- dbgprt("read_data: INIT len=%lu buf='%s'\n",data->len,data->buf);
- data->buf[data->len++] = '\n';
- }
- // get amount remaining to read
- retlen = data->len - xoff;
- if (retlen <= 0) {
- dbgprt("read_data: NORESID retlen=%ld\n",retlen);
- return 0;
- }
- // limit transfer size to buffer maximum
- if (retlen > len)
- retlen = len;
- do {
- // nothing to do
- if (retlen <= 0)
- break;
- // copy data to userspace
- err = copy_to_user(buf,&data->buf[xoff],retlen);
- // handle error on transfer
- if (err) {
- retlen = err;
- break;
- }
- // advance the file position
- xoff += retlen;
- *off = xoff;
- } while (0);
- dbgprt("read_data: EXIT retlen=%ld xoff=%lld\n",retlen,xoff);
- return retlen;
- }
- /* File operation on proc */
- static struct file_operations fops = {
- .owner = THIS_MODULE,
- #if 1
- .open = jiff_open,
- .release = jiff_release,
- #endif
- .read = read_data,
- };
- /* Init of kernel module */
- static int __init
- myInit(void)
- {
- /* Create proc file with name of jiffies */
- my_proc = proc_create(PROC_NAME, 0666, NULL, &fops);
- if (my_proc == NULL) {
- printk(KERN_INFO "Error to create proc File\n");
- return -1;
- }
- return 0;
- }
- /* exit of kernel module */
- static void
- myExit(void)
- {
- remove_proc_entry(PROC_NAME, NULL);
- return;
- }
- module_init(myInit);
- module_exit(myExit);
- % jiffdvr/test.c
- // test -- test program for jiffies driver
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <string.h>
- #include <errno.h>
- #define sysfault(_fmt...) \
- do { \
- printf(_fmt); \
- exit(1); \
- } while (0)
- void
- getjiff(int fd)
- {
- char buf[1];
- int totlen = 0;
- lseek(fd,0,0);
- while (totlen < 50) {
- int curlen = read(fd,buf,sizeof(buf));
- if (curlen == 0)
- break;
- if (curlen < 0) {
- sysfault("getjiff: read error -- %s\n",strerror(errno));
- break;
- }
- for (int idx = 0; idx < curlen; ++idx) {
- #if 1
- fputc(buf[idx],stdout);
- #else
- printf("idx=%d '%c'\n",idx,buf[idx]);
- #endif
- }
- totlen += curlen;
- }
- }
- int
- main(void)
- {
- int fd = open("/proc/jiffies",O_RDONLY);
- if (fd < 0)
- sysfault("main: unable to open -- %s\n",strerror(errno));
- for (int iter = 1; iter <= 5; ++iter) {
- getjiff(fd);
- usleep(10000);
- }
- close(fd);
- return 0;
- }
- % jiffdvr/Makefile
- # Makefile -- makefile for jiffies driver
- MNAME = jiffies
- obj-m += $(MNAME).o
- TEST = test
- all: build $(TEST)
- # build the driver
- build:
- make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
- clean:
- rm -f $(TEST)
- make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
- # load the driver
- load:
- shazam insmod $(MNAME).ko
- # unload the driver
- unload:
- -shazam rmmod $(MNAME)
- # reload the driver
- reload: unload load
- # create userspace test program
- $(TEST): $(TEST).c
- cc -o $(TEST) -DTEST $(TEST).c
- # run user test program
- run:
- ./$(TEST)
Add Comment
Please, Sign In to add comment