>Number:         6398
>Category:       user
>Synopsis:       GNU cvs import allows recursive mkdir(2); opencvs does not
>Confidential:   yes
>Severity:       serious
>Priority:       medium
>Responsible:    bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   unknown
>Arrival-Date:   Tue Jun 08 12:40:01 GMT 2010
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        
>Organization:
>Environment:
        System      : OpenBSD 4.7
        Details     : OpenBSD 4.7 (GENERIC) #558: Wed Mar 17 20:46:15 MDT 2010
                         
[email protected]:/usr/src/sys/arch/i386/compile/GENERIC

        Architecture: OpenBSD.i386
        Machine     : i386
>Description:
When importing, opencvs does not support the recursive mkdir(2) call that GNU 
cvs does.
Any scripts depending on this feature would break on opencvs.
One solution is to add a function cvs_mkdir() to call from import.c in place of 
mkdir(2).
Sample code follows.

>How-To-Repeat:
$ mkdir ~/repo
$ ./opencvs -d ~/repo init
$ ./opencvs -d ~/repo import -m 'test' some/nested/dir mwb start
opencvs [import aborted]: cvs_import: /home/mwb/repo/some/nested/dir: No such 
file or directory

# Concurrent Versions System (CVS) 1.11.1p1 (client/server)
$ mkdir ~/repo2
$ cvs -d ~/repo2 init
$ cvs -d ~/repo2 import -m 'test' some/nested/dir mwb start
N some/nested/dir/USELESS_FILE

No conflicts created by this import

>Fix:
$ cvs diff -u util.c util.h import.c
Index: util.c
===================================================================
RCS file: /cvs/src/usr.bin/cvs/util.c,v
retrieving revision 1.151
diff -u -r1.151 util.c
--- util.c      24 Mar 2009 06:59:19 -0000      1.151
+++ util.c      8 Jun 2010 07:57:07 -0000
@@ -682,6 +682,59 @@
        xfree(dir);
 }

+void
+cvs_mkdir(const char *path, mode_t mode)
+{
+       size_t len;
+       struct hash_data *hdata, hd;
+       char *sp, *dp, *dir, rpath[MAXPATHLEN];
+
+       hdata = hash_table_find(&created_directories, path, strlen(path));
+       if (hdata != NULL)
+               return;
+
+       hd.h_key = xstrdup(path);
+       hd.h_data = NULL;
+       hash_table_enter(&created_directories, &hd);
+
+       if (current_cvsroot->cr_method != CVS_METHOD_LOCAL ||
+           cvs_server_active == 1)
+               cvs_validate_directory(path);
+
+       dir = xstrdup(path);
+
+       STRIP_SLASH(dir);
+
+       if (cvs_server_active == 0)
+               cvs_log(LP_TRACE, "cvs_mkdir(%s)", dir);
+
+       rpath[0] = '\0';
+
+       for (sp = dir; sp != NULL; sp = dp) {
+               dp = strchr(sp, '/');
+               if (dp != NULL)
+                       *(dp++) = '\0';
+
+               len = strlcat(rpath, "/", sizeof(rpath));
+               if (len >= (int)sizeof(rpath))
+                       fatal("cvs_mkdir: overflow");
+
+               len = strlcat(rpath, sp, sizeof(rpath));
+               if (len >= (int)sizeof(rpath))
+                       fatal("cvs_mkdir: overflow");
+               if (1 == len)
+                       continue;
+
+               if (mkdir(rpath, mode) == -1 && errno != EEXIST)
+                       fatal("cvs_mkdir: %s: %s", rpath, strerror(errno));
+
+               if (cvs_cmdop == CVS_OP_EXPORT && !cvs_server_active)
+                       continue;
+       }
+
+       xfree(dir);
+}
+
 /*
  * Split the contents of a file into a list of lines.
  */
Index: util.h
===================================================================
RCS file: /cvs/src/usr.bin/cvs/util.h,v
retrieving revision 1.26
diff -u -r1.26 util.h
--- util.h      12 Jun 2008 07:16:14 -0000      1.26
+++ util.h      8 Jun 2010 07:57:07 -0000
@@ -33,6 +33,7 @@
 void     cvs_strtomode(const char *, mode_t *);
 void     cvs_mkadmin(const char *, const char *, const char *, char *, char *);
 void     cvs_mkpath(const char *, char *);
+void     cvs_mkdir(const char *, mode_t);
 int      cvs_cksum(const char *, char *, size_t);
 int      cvs_getargv(const char *, char **, int);
 int      cvs_chdir(const char *, int);
Index: import.c
===================================================================
RCS file: /cvs/src/usr.bin/cvs/import.c,v
retrieving revision 1.101
diff -u -r1.101 import.c
--- import.c    27 Jun 2009 16:55:31 -0000      1.101
+++ import.c    8 Jun 2010 07:57:07 -0000
@@ -162,8 +162,7 @@
        import_loginfo(import_repository);

        if (cvs_noexec != 1) {
-               if (mkdir(repo, 0755) == -1 && errno != EEXIST)
-                       fatal("cvs_import: %s: %s", repo, strerror(errno));
+               cvs_mkdir(repo, 0755);
        }

        cr.enterdir = NULL;

$ ./opencvs -d $CVSROOT import -m "test" some/nested/dir mwb start
N some/nested/dir/USELESS_FILE
N some/nested/dir/asdndfg

No conflicts created by this import.


dmesg:
OpenBSD 4.7 (GENERIC) #558: Wed Mar 17 20:46:15 MDT 2010
    [email protected]:/usr/src/sys/arch/i386/compile/GENERIC
cpu0: Intel Pentium II ("GenuineIntel" 686-class) 2.66 GHz
cpu0: 
FPU,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,PGE,CMOV,PAT,MMX,FXSR,SSE,SSE2,SSE3
real mem  = 133722112 (127MB)
avail mem = 120918016 (115MB)
mainbus0 at root
bios0 at mainbus0: AT/286+ BIOS, date 11/01/06, BIOS32 rev. 0 @ 0xfa0d0
apm0 at bios0: Power Management spec V1.2
apm0: AC on, battery charge unknown
pcibios0 at bios0: rev 2.1 @ 0xf0000/0x0
pcibios0: PCI IRQ Routing Table rev 1.0 @ 0xfa3c0/128 (6 entries)
pcibios0: PCI Interrupt Router at 000:01:0 ("Intel 82371SB ISA" rev 0x00)
pcibios0: PCI bus #0 is the last bus
bios0: ROM list: 0xc0000/0x8a00
cpu0 at mainbus0: (uniprocessor)
pci0 at mainbus0 bus 0: configuration mode 1 (bios)
pchb0 at pci0 dev 0 function 0 "Intel 82441FX" rev 0x02
pcib0 at pci0 dev 1 function 0 "Intel 82371SB ISA" rev 0x00
pciide0 at pci0 dev 1 function 1 "Intel 82371SB IDE" rev 0x00: DMA, channel 0 
wired to compatibility, channel 1 wired to compatibility
wd0 at pciide0 channel 0 drive 0: <QEMU HARDDISK>
wd0: 16-sector PIO, LBA48, 1000MB, 2048000 sectors
wd0(pciide0:0:0): using PIO mode 0, DMA mode 2
atapiscsi0 at pciide0 channel 1 drive 0
scsibus0 at atapiscsi0: 2 targets
cd0 at scsibus0 targ 0 lun 0: <QEMU, QEMU DVD-ROM, 0.9.> ATAPI 5/cdrom removable
cd0(pciide0:1:0): using PIO mode 0
piixpm0 at pci0 dev 1 function 3 "Intel 82371AB Power" rev 0x03: irq 11
iic0 at piixpm0
iic0: addr 0x18 00=d0 01=d0 02=d0 03=d0 04=d0 05=d0 06=d0 07=d0 08=d0 words 
00=0000 01=0000 02=0000 03=0000 04=0000 05=0000 06=0000 07=0000
iic0: addr 0x1a 00=d0 01=d0 02=d0 03=d0 04=d0 05=d0 06=d0 07=d0 08=d0 words 
00=0000 01=0000 02=0000 03=0000 04=0000 05=0000 06=0000 07=0000
iic0: addr 0x1c 0f=d0 words 00=0000 01=0000 02=0000 03=0000 04=0000 05=0000 
06=0000 07=0000
iic0: addr 0x1d 0f=d0 words 00=0000 01=0000 02=0000 03=0000 04=0000 05=0000 
06=0000 07=0000
iic0: addr 0x4c 00=d0 01=d0 02=d0 03=d0 04=d0 05=d0 06=d0 07=d0 08=d0 words 
00=0000 01=0000 02=0000 03=0000 04=0000 05=0000 06=0000 07=0000
iic0: addr 0x4e 00=d0 01=d0 02=d0 03=d0 04=d0 05=d0 06=d0 07=d0 08=d0 words 
00=0000 01=0000 02=0000 03=0000 04=0000 05=0000 06=0000 07=0000
vga1 at pci0 dev 2 function 0 "Cirrus Logic CL-GD5446" rev 0x00
wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
ne3 at pci0 dev 3 function 0 "Realtek 8029" rev 0x00: irq 11, address 
52:54:00:12:34:56
isa0 at pcib0
isadma0 at isa0
com0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
com0: probed fifo depth: 0 bytes
pckbc0 at isa0 port 0x60/5
pckbd0 at pckbc0 (kbd slot)
pckbc0: using irq 1 for kbd slot
wskbd0 at pckbd0: console keyboard, using wsdisplay0
pms0 at pckbc0 (aux slot)
pckbc0: using irq 12 for aux slot
wsmouse0 at pms0 mux 0
pcppi0 at isa0 port 0x61
midi0 at pcppi0: <PC speaker>
spkr0 at pcppi0
lpt0 at isa0 port 0x378/4 irq 7
npx0 at isa0 port 0xf0/16: reported by CPUID; using exception 16
fdc0 at isa0 port 0x3f0/6 irq 6 drq 2
fd0 at fdc0 drive 0: density unknown
fd1 at fdc0 drive 1: density unknown
biomask ef6d netmask ef6d ttymask ffff
nvram: invalid checksum
vscsi0 at root
scsibus1 at vscsi0: 256 targets
softraid0 at root
root on wd0a swap on wd0b dump on wd0b
clock: unknown CMOS layout


>Release-Note:
>Audit-Trail:
>Unformatted:

Reply via email to