#ifndef __KERNEL__ #define __KERNEL__ #endif #ifndef MODULE #define MODULE #endif #include #include #include char *src = NULL; char *dst = NULL; MODULE_PARM(src,"s"); MODULE_PARM(dst,"s"); /* This is a kernel module, I must be very * carefull to clean up everything myself, * there is nobody who can do it for me. */ int init_module(void) { struct file *srcf,*dstf; int retval,orgfsuid,orgfsgid; mm_segment_t orgfs; char *buffer; unsigned long page; /* Save uid and gid used for filesystem access. * Set user and group to 0 (root) */ orgfsuid=current->fsuid; orgfsgid=current->fsgid; current->fsuid=current->fsgid=0; /* save FS register and set FS register to kernel * space, needed for read and write to accept * buffer in kernel space. */ orgfs=get_fs(); set_fs(KERNEL_DS); if (src&&dst&&*src&&*dst) { printk("Copying %s to %s\n",src,dst); /* Allocate one page for buffer */ page = __get_free_page(GFP_KERNEL); if (page) { buffer=(char*)page; srcf = filp_open(src, O_RDONLY, 0); if (IS_ERR(srcf)) { printk("kcp: Error %ld opening %s\n",-PTR_ERR(srcf),src); } else { /* The object must have a read method */ if (srcf->f_op&&srcf->f_op->read) { dstf = filp_open(dst, O_WRONLY|O_TRUNC|O_CREAT , 0644); if (IS_ERR(dstf)) { printk("kcp: Error %ld opening %s\n",-PTR_ERR(dstf),dst); } else { /* The object must have a write method */ if (dstf->f_op&&dstf->f_op->write) { do { /* Read as much as posible into the buffer, * at most one page. */ retval=srcf->f_op->read(srcf,buffer,PAGE_SIZE,&srcf->f_pos); if (retval<0) printk("kcp: Read error %d\n",-retval); if (retval>0) { int index=0,bufsize=retval; /* Continue writing until error or everything * written. */ while ((indexf_op->write (dstf,buffer+index,bufsize-index,&dstf->f_pos))>0) ) index+=retval; if (index0); /* Now clean up everything that was actually allocated */ } else { printk("kcp: %s does not have a write method\n",dst); } retval=filp_close(dstf,NULL); if (retval) printk("kcp: Error %d closing %s\n",-retval,dst); } } else { printk("kcp: %s does not have a read method\n",src); } retval=filp_close(srcf,NULL); if (retval) printk("kcp: Error %d closing %s\n",-retval,src); } free_page(page); } else { printk("kcp: Out of memory\n"); } } else printk("kcp: Both src= and dst= must be specified\n"); set_fs(orgfs); current->fsuid=orgfsuid; current->fsgid=orgfsgid; /* End of demo, returning an error code * makes insmod/modprobe remove the module * from memory. */ return 1; }