From nobody@FreeBSD.org  Sat Sep 23 01:52:46 2006
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 7655016A412
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 23 Sep 2006 01:52:46 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id F043F43D49
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 23 Sep 2006 01:52:44 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id k8N1qilB002364
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 23 Sep 2006 01:52:44 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id k8N1qihu002363;
	Sat, 23 Sep 2006 01:52:44 GMT
	(envelope-from nobody)
Message-Id: <200609230152.k8N1qihu002363@www.freebsd.org>
Date: Sat, 23 Sep 2006 01:52:44 GMT
From: Yoshihiro Ota <ota@j.email.ne.jp>
To: freebsd-gnats-submit@FreeBSD.org
Subject: mkuzip enhancement to accept size of input file
X-Send-Pr-Version: www-2.3

>Number:         103500
>Category:       bin
>Synopsis:       [patch] mkuzip(1) enhancement to accept size of input file
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    fjoe
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Sep 23 02:00:38 GMT 2006
>Closed-Date:    Tue Mar 06 17:06:32 GMT 2007
>Last-Modified:  Tue Mar  6 17:10:05 GMT 2007
>Originator:     Yoshihiro Ota
>Release:        6.[01]-RELEASE, 6.2-PRERELEASE
>Organization:
>Environment:
FreeBSD xxx.yyy.com 6.2-PRERELEASE FreeBSD 6.2-PRERELEASE #23: Wed Sep 20 00:16:08 EST 2006     root@xxx.yyy.com:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
mkuzip cannot compress devices because stat.2 does not return the size of
devices.  The patch attached allows mkuzip to prcocess non-stat.2 sizeable
files such as device.

mkuzip takes new -S size option as expected size of the input file.  If EOF
reaches before the size, the new mkuzip creates one empty block and all
remaining block pointers points to the empty block.  If size is too small,
it exists with error.
>How-To-Repeat:
mkuzip -o /var/tmp/tmp.uzip /dev/ad0s1a
>Fix:
--- src.org/usr.bin/mkuzip/mkuzip.c     Sat Apr 15 17:10:12 2006
+++ src/usr.bin/mkuzip/mkuzip.c Tue Apr 18 06:14:53 2006
@@ -24,6 +24,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <inttypes.h>
 
 #define CLSTSIZE       16384
 #define DEFAULT_SUFX   ".uzip"
@@ -33,6 +34,7 @@
     "m=geom_uzip\n(kldstat -m $m 2>&-||kldload $m)>&-&&"
     "mount_cd9660 /dev/`mdconfig -af $0`.uzip $1\nexit $?\n";
  
+static uint32_t get_size(char *);
 static char *readblock(int, char *, u_int32_t);
 static void usage(void);
 static void *safe_malloc(size_t);
@@ -43,12 +45,16 @@
 int main(int argc, char **argv)
 {
        char *iname, *oname, *obuf, *ibuf;
+       char *p;
        uint64_t *toc;
-       int fdr, fdw, i, opt, verbose, tmp;
+       int fdr, fdw, opt, verbose, tmp;
        struct iovec iov[2];
-       struct stat sb;
        uLongf destlen;
        uint64_t offset;
+       off_t i;
+       off_t *inputsz; /* we try file size first; otherwise user supplied */
+       off_t filesz; /* file size */
+       off_t usersz; /* user supplied size */
        struct cloop_header {
                char magic[CLOOP_MAGIC_LEN];    /* cloop magic */
                uint32_t blksz;                 /* block size */
@@ -61,7 +67,7 @@
        oname = NULL;
        verbose = 0;

-       while((opt = getopt(argc, argv, "o:s:v")) != -1) {
+       while((opt = getopt(argc, argv, "o:s:S:v")) != -1) {
                switch(opt) {
                case 'o':
                        oname = optarg;
@@ -86,6 +92,27 @@
                        hdr.blksz = tmp;
                        break;

+               case 'S':
+                       usersz = (off_t)strtoumax(optarg, &p, 0);
+                       if(p == NULL || *p == '\0')
+                               break;
+                       switch(*p)
+                       {
+                               case 't': case 'T':
+                                       usersz <<= 10;
+                               case 'g': case 'G':
+                                       usersz <<= 10;
+                               case 'm': case 'M':
+                                       usersz <<= 10;
+                               case 'k': case 'K':
+                                       usersz <<= 10;
+                               case 'b': case 'B':
+                                       break;
+                               default:
+                                       err(1, "Unknown suffix on -S argument");
+                       }
+                       break;
+
                case 'v':
                        verbose = 1;
                        break;
@@ -122,12 +149,21 @@
        signal(SIGXFSZ, exit);
        atexit(cleanup);

-       if (stat(iname, &sb) != 0) {
-               err(1, "%s", iname);
+
+       filesz = get_size(iname);
+       if(filesz > 0)
+               inputsz = &filesz;
+       else
+               inputsz = &usersz;
+
+       if(*inputsz < 0) {
+               err(1, "input file size is not avaiable;\n"
+                       "try -S input_size option with large enough size");
                /* Not reached */
        }
-       hdr.nblocks = sb.st_size / hdr.blksz;
-       if ((sb.st_size % hdr.blksz) != 0) {
+
+       hdr.nblocks = *inputsz / hdr.blksz;
+       if ((*inputsz % hdr.blksz) != 0) {
                if (verbose != 0)
                        fprintf(stderr, "file size is not multiple "
                        "of %d, padding data\n", hdr.blksz);
@@ -160,21 +196,23 @@

        if (verbose != 0)
                fprintf(stderr, "data size %ju bytes, number of clusters "
-                   "%u, index length %zu bytes\n", sb.st_size,
+                   "%u, index length %zu bytes\n", *inputsz,
                    hdr.nblocks, iov[1].iov_len);

-       for(i = 0; i == 0 || ibuf != NULL; i++) {
-               ibuf = readblock(fdr, ibuf, hdr.blksz);
-               if (ibuf != NULL) {
-                       destlen = compressBound(hdr.blksz);
-                       if (compress2(obuf, &destlen, ibuf, hdr.blksz,
-                           Z_BEST_COMPRESSION) != Z_OK) {
-                               errx(1, "can't compress data: compress2() "
-                                   "failed");
+       for(i = 0; i <= hdr.nblocks; i++) {
+               p = readblock(fdr, ibuf, hdr.blksz);
+
+               /* compress 0'ed data even if no data is read */
+               destlen = compressBound(hdr.blksz);
+               if (compress2(obuf, &destlen, ibuf, hdr.blksz,
+                       Z_BEST_COMPRESSION) != Z_OK) {
+                               errx(1, "can't compress data: compress2() failed
");
                                /* Not reached */
-                       }
+               }
+
+               if (p != NULL) {
                        if (verbose != 0)
-                               fprintf(stderr, "cluster #%d, in %u bytes, "
+                               fprintf(stderr, "cluster #%ju, in %u bytes, "
                                    "out %lu bytes\n", i, hdr.blksz, destlen);
                } else {
                        destlen = DEV_BSIZE - (offset % DEV_BSIZE);
@@ -189,14 +227,27 @@
                        /* Not reached */
                }
                toc[i] = htobe64(offset);
+               if(p == NULL) {
+                       /* -S size was too large; the rest points to zero filled
 block */
+                       for(; i <= hdr.nblocks; i++)
+                               toc[i] = htobe64(offset);
+                       break;
+               }
                offset += destlen;
        }
+       if(p != NULL && i > hdr.nblocks) { /* check if we can read more */
+               if(readblock(fdr, ibuf, hdr.blksz) != NULL) {
+                       /* file has grown or -S was too smal */
+                       err(1, "uziped file was not large enought");
+                       /* Not reached */
+               }
+       }
        close(fdr);

        if (verbose != 0)
                fprintf(stderr, "compressed data to %ju bytes, saved %lld "
-                   "bytes, %.2f%% decrease.\n", offset, (long long)(sb.st_size
- offset),
-                   100.0 * (long long)(sb.st_size - offset) / (float)sb.st_size
);
+                   "bytes, %.2f%% decrease.\n", offset, (long long)(*inputsz -
offset),
+                   100.0 * (long long)(*inputsz - offset) / (float)*inputsz);

        /* Convert to big endian */
        hdr.blksz = htonl(hdr.blksz);
@@ -213,6 +264,20 @@
        exit(0);
 }

+static uint32_t
+get_size(char *filename)
+{
+       struct stat sb;
+       if (stat(filename, &sb) != 0) {
+               err(1, "%s", filename);
+               /* Not reached */
+       }
+       if(sb.st_size > 0) /* we got the actual size */
+               return sb.st_size;
+
+       return 0;
+}
+
 static char *
 readblock(int fd, char *ibuf, u_int32_t clstsize)
 {
@@ -234,7 +299,9 @@
 usage(void)
 {

-       fprintf(stderr, "usage: mkuzip [-v] [-o outfile] [-s cluster_size] infil
e\n");
+       fprintf(stderr,
+               "usage: mkuzip [-v] [-o outfile] "
+               "[-s cluster_size] [-S input_size] infile\n");
        exit(1);
 }


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->	 fjoe 
Responsible-Changed-By: matteo 
Responsible-Changed-When: Thu Feb 15 16:45:57 UTC 2007 
Responsible-Changed-Why:  
Assigno to fjoe@ as original uzip's writer 

http://www.freebsd.org/cgi/query-pr.cgi?pr=103500 
State-Changed-From-To: open->closed 
State-Changed-By: fjoe 
State-Changed-When: Tue Mar 6 17:05:15 UTC 2007 
State-Changed-Why:  
Fixed. Now character device size is obtained using DIOCGMEDIASIZE. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=103500 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/103500: commit references a PR
Date: Tue,  6 Mar 2007 17:04:28 +0000 (UTC)

 fjoe        2007-03-06 17:04:15 UTC
 
   FreeBSD src repository
 
   Modified files:
     usr.bin/mkuzip       mkuzip.c 
   Log:
   Support character device as input file.
   
   PR:             103500
   
   Revision  Changes    Path
   1.6       +21 -7     src/usr.bin/mkuzip/mkuzip.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
>Unformatted:
