diff options
author | HyungKyu Song <hk76.song@samsung.com> | 2013-02-16 00:51:52 +0900 |
---|---|---|
committer | HyungKyu Song <hk76.song@samsung.com> | 2013-02-16 00:51:52 +0900 |
commit | 49807896eda1a7081cce1a7a134fb0071f5e7eeb (patch) | |
tree | aef757b2abf225284bf0ccb0df3a7b7aab6765aa /theos/_rename.c | |
parent | 3101b2a7be8f0e3cc6ff469ce2597945c862264b (diff) | |
download | zip-49807896eda1a7081cce1a7a134fb0071f5e7eeb.tar.gz zip-49807896eda1a7081cce1a7a134fb0071f5e7eeb.tar.bz2 zip-49807896eda1a7081cce1a7a134fb0071f5e7eeb.zip |
Diffstat (limited to 'theos/_rename.c')
-rw-r--r-- | theos/_rename.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/theos/_rename.c b/theos/_rename.c new file mode 100644 index 0000000..04eb204 --- /dev/null +++ b/theos/_rename.c @@ -0,0 +1,83 @@ +/* + Copyright (c) 1990-1999 Info-ZIP. All rights reserved. + + See the accompanying file LICENSE, version 1999-Oct-05 or later + (the contents of which are also included in zip.h) for terms of use. + If, for some reason, both of these files are missing, the Info-ZIP license + also may be found at: ftp://ftp.cdrom.com/pub/infozip/license.html +*/ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#define EXDEV 590 + +#define _sys_rename() _sc_140() +extern unsigned short _sys_rename(const char _far *oldfn, char *newfn); + +/* rename a file. Report an error on cross disk renames */ + +static void _n_(const char* fn, char* bfn) +{ + if (*fn != '.' && *fn != '/') + strcpy(bfn, "./"); + else + *bfn = '\0'; + strcat(bfn, fn); +} + +int _rename(const char* old, const char* new) +{ + char* p; + char* q; + char* r; + char olddrv, newdrv; + char dir[FILENAME_MAX]; + short status; + char bold[FILENAME_MAX], bnew[FILENAME_MAX]; + + p = strrchr(old, ':'); + q = strrchr(new, ':'); + + /* if at least one path includes a disk name, check for equality */ + if (p != NULL || q != NULL) { + /* getcwd return a NULL pointer for /:S */ + getcwd(dir, FILENAME_MAX); + r = strrchr(dir, ':'); + + if (p == NULL) + p = r; + olddrv = p ? p[1] : 'S'; + + if (q == NULL) + q = r; + newdrv = q ? q[1] : 'S'; + + /* return an error if uppercased disk names are not the same */ + if ((old & ~0x20) != (new & ~0x20)) { + _errarg = NULL; + return errno = _errnum = EXDEV; + } + } + /* prepend ./ if there is no path to force rename to work on files + * in the current directory instead of default library + */ + _n_(old, bold); + _n_(new, bnew); + + status = _sys_rename(bold, bnew); + /* can be : + * 0 no error + * 19 "old" file not found + * 44 "new" file already exist + * 45 "new" filename missing + * 46 "old" file name missing + */ + if (status) { + errno = _errnum = status; + _errarg = (status == 44 || status == 45) ? new : old; + } + + return status; +} |