>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: