Copying the qemu-devel mailing list too. On Wed, 2009-06-24 at 09:58 -0700, Ram Pai wrote: > Problem: It is impossible to feed filenames with the character colon because > qemu interprets such names as a protocol. For example a filename scsi:0, > is interpreted as a protocol by name "scsi". > > This patch allows users to espace colon characters. For example the above filename > can now be expressed as 'scsi\:0' > > Here are couple of examples: > > ndb:\::9999 is treated as a ndb protocol with a hostname ':' on port 9999 > scsi\:0\:abc is a local file scsi:0:abc > http\://myweb is a local file by name http://myweb > nbd\::localhost:2558 is a protocol by name nbd: > > Signed-off-by: Ram Pai <linuxram@xxxxxxxxxx> > ----------------------------------------------------------------------- > > > block.c | 26 +++++++++++++++++--------- > block/nbd.c | 19 ++++++++++++++----- > block/raw-posix.c | 24 +++++++++++++++++------- > cutils.c | 22 ++++++++++++++++++++++ > qemu-common.h | 1 + > vl.c | 3 +-- > 6 files changed, 72 insertions(+), 23 deletions(-) > > diff --git a/block.c b/block.c > index aca5a6d..80bded9 100644 > --- a/block.c > +++ b/block.c > @@ -225,22 +225,30 @@ static BlockDriver *find_protocol(const char *filename) > { > BlockDriver *drv1; > char protocol[128]; > - int len; > - const char *p; > + char *p = protocol; > + const char *f=filename; > + int len = strnlen(filename, 128); > > #ifdef _WIN32 > if (is_windows_drive(filename) || > is_windows_drive_prefix(filename)) > return bdrv_find_format("raw"); > #endif > - p = strchr(filename, ':'); > - if (!p) > + while ( f < filename+len ) { > + if ( *f == ':' ) > + break; > + if ( *f == '\\') { > + f++; > + if ( *f == '\0') > + break; > + } > + *p++ = *f++; > + } > + *p='\0'; > + > + if (*f != ':') > return bdrv_find_format("raw"); > - len = p - filename; > - if (len > sizeof(protocol) - 1) > - len = sizeof(protocol) - 1; > - memcpy(protocol, filename, len); > - protocol[len] = '\0'; > + > for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) { > if (drv1->protocol_name && > !strcmp(drv1->protocol_name, protocol)) > diff --git a/block/nbd.c b/block/nbd.c > index 47d4778..a011cc7 100644 > --- a/block/nbd.c > +++ b/block/nbd.c > @@ -64,18 +64,27 @@ static int nbd_open(BlockDriverState *bs, const char* filename, int flags) > > } else { > uint16_t port; > - char *p, *r; > + char *q, *p, *r; > char hostname[128]; > > pstrcpy(hostname, 128, host); > > - p = strchr(hostname, ':'); > - if (p == NULL) > + q=p=hostname; > + while ( p < hostname+128 ) { > + if (*p == ':') > + break; > + if ( *p == '\\' ) { > + p++; > + if (*p =='\0') > + break; > + } > + *q++=*p++; > + } > + if (*p != ':') > return -EINVAL; > > - *p = '\0'; > + *q='\0'; > p++; > - > port = strtol(p, &r, 0); > if (r == p) > return -EINVAL; > diff --git a/block/raw-posix.c b/block/raw-posix.c > index 41bfa37..98ede17 100644 > --- a/block/raw-posix.c > +++ b/block/raw-posix.c > @@ -124,6 +124,16 @@ static int fd_open(BlockDriverState *bs); > static int cdrom_reopen(BlockDriverState *bs); > #endif > > +static int _open(const char *filename, int flags, ...) > +{ > + char myfile[PATH_MAX]; > + va_list ap; > + va_start(ap, flags); > + return open(esc_string(myfile, PATH_MAX, filename), > + flags, ap); > +} > + > + > static int raw_open_common(BlockDriverState *bs, const char *filename, > int flags) > { > @@ -151,7 +161,7 @@ static int raw_open_common(BlockDriverState *bs, const char *filename, > s->open_flags |= O_DSYNC; > > s->fd = -1; > - fd = open(filename, s->open_flags, 0644); > + fd = _open(filename, s->open_flags, 0644); > if (fd < 0) { > ret = -errno; > if (ret == -EROFS) > @@ -844,7 +854,7 @@ static int raw_create(const char *filename, QEMUOptionParameter *options) > options++; > } > > - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, > + fd = _open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, > 0644); > if (fd < 0) > return -EIO; > @@ -985,7 +995,7 @@ static int hdev_open(BlockDriverState *bs, const char *filename, int flags) > if ( bsdPath[ 0 ] != '\0' ) { > strcat(bsdPath,"s0"); > /* some CDs don't have a partition 0 */ > - fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); > + fd = _open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); > if (fd < 0) { > bsdPath[strlen(bsdPath)-1] = '1'; > } else { > @@ -1037,7 +1047,7 @@ static int fd_open(BlockDriverState *bs) > #endif > return -EIO; > } > - s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK); > + s->fd = _open(bs->filename, s->open_flags & ~O_NONBLOCK); > if (s->fd < 0) { > s->fd_error_time = qemu_get_clock(rt_clock); > s->fd_got_error = 1; > @@ -1133,7 +1143,7 @@ static int hdev_create(const char *filename, QEMUOptionParameter *options) > options++; > } > > - fd = open(filename, O_WRONLY | O_BINARY); > + fd = _open(filename, O_WRONLY | O_BINARY); > if (fd < 0) > return -EIO; > > @@ -1239,7 +1249,7 @@ static int floppy_eject(BlockDriverState *bs, int eject_flag) > close(s->fd); > s->fd = -1; > } > - fd = open(bs->filename, s->open_flags | O_NONBLOCK); > + fd = _open(bs->filename, s->open_flags | O_NONBLOCK); > if (fd >= 0) { > if (ioctl(fd, FDEJECT, 0) < 0) > perror("FDEJECT"); > @@ -1399,7 +1409,7 @@ static int cdrom_reopen(BlockDriverState *bs) > */ > if (s->fd >= 0) > close(s->fd); > - fd = open(bs->filename, s->open_flags, 0644); > + fd = _open(bs->filename, s->open_flags, 0644); > if (fd < 0) { > s->fd = -1; > return -EIO; > diff --git a/cutils.c b/cutils.c > index 6ea0c49..63c196d 100644 > --- a/cutils.c > +++ b/cutils.c > @@ -24,6 +24,28 @@ > #include "qemu-common.h" > #include "host-utils.h" > > +/* > + * prune escape character '\' > + */ > +char *esc_string(char *buf, int buf_size, const char *str) > +{ > + const char *p=str; > + int len = strlen(str); > + char *q=buf; > + > + len = (buf_size < len) ? buf_size: len; > + while (p < str+len) { > + if (*p == '\\') { > + p++; > + if (*p == '\0') > + break; > + } > + *q++ = *p++; > + } > + *q='\0'; > + return buf; > +} > + > void pstrcpy(char *buf, int buf_size, const char *str) > { > int c; > diff --git a/qemu-common.h b/qemu-common.h > index 2dcb224..1e510dc 100644 > --- a/qemu-common.h > +++ b/qemu-common.h > @@ -104,6 +104,7 @@ void qemu_get_timedate(struct tm *tm, int offset); > int qemu_timedate_diff(struct tm *tm); > > /* cutils.c */ > +char *esc_string(char *buf, int buf_size, const char *str); > void pstrcpy(char *buf, int buf_size, const char *str); > char *pstrcat(char *buf, int buf_size, const char *s); > int strstart(const char *str, const char *val, const char **ptr); > diff --git a/vl.c b/vl.c > index 7278999..5d7b024 100644 > --- a/vl.c > +++ b/vl.c > @@ -2583,8 +2583,7 @@ int drive_init(struct drive_opt *arg, int snapshot, void *opaque) > else if (cache == 3) /* not specified */ > bdrv_flags |= BDRV_O_CACHE_DEF; > if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0) { > - fprintf(stderr, "qemu: could not open disk image %s\n", > - file); > + fprintf(stderr, "qemu: could not open disk image %s\n", file); > return -1; > } > if (bdrv_key_required(bdrv)) > > > > -- > To unsubscribe from this list: send the line "unsubscribe kvm" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html