Changeset View
Changeset View
Standalone View
Standalone View
stable/10/sys/fs/msdosfs/msdosfs_conv.c
Show First 20 Lines • Show All 672 Lines • ▼ Show 20 Lines | win2unixfn(nbp, wep, chksum, pmp) | ||||
* Convert the name parts | * Convert the name parts | ||||
*/ | */ | ||||
np = name; | np = name; | ||||
for (cp = wep->wePart1, i = sizeof(wep->wePart1)/2; --i >= 0;) { | for (cp = wep->wePart1, i = sizeof(wep->wePart1)/2; --i >= 0;) { | ||||
code = (cp[1] << 8) | cp[0]; | code = (cp[1] << 8) | cp[0]; | ||||
switch (code) { | switch (code) { | ||||
case 0: | case 0: | ||||
*np = '\0'; | *np = '\0'; | ||||
mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); | if (mbnambuf_write(nbp, name, | ||||
(wep->weCnt & WIN_CNT) - 1) != 0) | |||||
return -1; | |||||
return chksum; | return chksum; | ||||
case '/': | case '/': | ||||
*np = '\0'; | *np = '\0'; | ||||
return -1; | return -1; | ||||
default: | default: | ||||
c = win2unixchr(tmpbuf, code, pmp); | c = win2unixchr(tmpbuf, code, pmp); | ||||
while (*c != '\0') | while (*c != '\0') | ||||
*np++ = *c++; | *np++ = *c++; | ||||
break; | break; | ||||
} | } | ||||
cp += 2; | cp += 2; | ||||
} | } | ||||
for (cp = wep->wePart2, i = sizeof(wep->wePart2)/2; --i >= 0;) { | for (cp = wep->wePart2, i = sizeof(wep->wePart2)/2; --i >= 0;) { | ||||
code = (cp[1] << 8) | cp[0]; | code = (cp[1] << 8) | cp[0]; | ||||
switch (code) { | switch (code) { | ||||
case 0: | case 0: | ||||
*np = '\0'; | *np = '\0'; | ||||
mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); | if (mbnambuf_write(nbp, name, | ||||
(wep->weCnt & WIN_CNT) - 1) != 0) | |||||
return -1; | |||||
return chksum; | return chksum; | ||||
case '/': | case '/': | ||||
*np = '\0'; | *np = '\0'; | ||||
return -1; | return -1; | ||||
default: | default: | ||||
c = win2unixchr(tmpbuf, code, pmp); | c = win2unixchr(tmpbuf, code, pmp); | ||||
while (*c != '\0') | while (*c != '\0') | ||||
*np++ = *c++; | *np++ = *c++; | ||||
break; | break; | ||||
} | } | ||||
cp += 2; | cp += 2; | ||||
} | } | ||||
for (cp = wep->wePart3, i = sizeof(wep->wePart3)/2; --i >= 0;) { | for (cp = wep->wePart3, i = sizeof(wep->wePart3)/2; --i >= 0;) { | ||||
code = (cp[1] << 8) | cp[0]; | code = (cp[1] << 8) | cp[0]; | ||||
switch (code) { | switch (code) { | ||||
case 0: | case 0: | ||||
*np = '\0'; | *np = '\0'; | ||||
mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); | if (mbnambuf_write(nbp, name, | ||||
(wep->weCnt & WIN_CNT) - 1) != 0) | |||||
return -1; | |||||
return chksum; | return chksum; | ||||
case '/': | case '/': | ||||
*np = '\0'; | *np = '\0'; | ||||
return -1; | return -1; | ||||
default: | default: | ||||
c = win2unixchr(tmpbuf, code, pmp); | c = win2unixchr(tmpbuf, code, pmp); | ||||
while (*c != '\0') | while (*c != '\0') | ||||
*np++ = *c++; | *np++ = *c++; | ||||
break; | break; | ||||
} | } | ||||
cp += 2; | cp += 2; | ||||
} | } | ||||
*np = '\0'; | *np = '\0'; | ||||
mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1); | if (mbnambuf_write(nbp, name, (wep->weCnt & WIN_CNT) - 1) != 0) | ||||
return -1; | |||||
return chksum; | return chksum; | ||||
} | } | ||||
/* | /* | ||||
* Compute the unrolled checksum of a DOS filename for Win95 LFN use. | * Compute the unrolled checksum of a DOS filename for Win95 LFN use. | ||||
*/ | */ | ||||
u_int8_t | u_int8_t | ||||
winChksum(u_int8_t *name) | winChksum(u_int8_t *name) | ||||
▲ Show 20 Lines • Show All 285 Lines • ▼ Show 20 Lines | |||||
* Fill out our concatenation buffer with the given substring, at the offset | * Fill out our concatenation buffer with the given substring, at the offset | ||||
* specified by its id. Since this function must be called with ids in | * specified by its id. Since this function must be called with ids in | ||||
* descending order, we take advantage of the fact that ASCII substrings are | * descending order, we take advantage of the fact that ASCII substrings are | ||||
* exactly WIN_CHARS in length. For non-ASCII substrings, we shift all | * exactly WIN_CHARS in length. For non-ASCII substrings, we shift all | ||||
* previous (i.e. higher id) substrings upwards to make room for this one. | * previous (i.e. higher id) substrings upwards to make room for this one. | ||||
* This only penalizes portions of substrings that contain more than | * This only penalizes portions of substrings that contain more than | ||||
* WIN_CHARS bytes when they are first encountered. | * WIN_CHARS bytes when they are first encountered. | ||||
*/ | */ | ||||
void | int | ||||
mbnambuf_write(struct mbnambuf *nbp, char *name, int id) | mbnambuf_write(struct mbnambuf *nbp, char *name, int id) | ||||
{ | { | ||||
char *slot; | char *slot; | ||||
size_t count, newlen; | size_t count, newlen; | ||||
if (nbp->nb_len != 0 && id != nbp->nb_last_id - 1) { | if (nbp->nb_len != 0 && id != nbp->nb_last_id - 1) { | ||||
#ifdef MSDOSFS_DEBUG | #ifdef MSDOSFS_DEBUG | ||||
printf("msdosfs: non-decreasing id: id %d, last id %d\n", | printf("msdosfs: non-decreasing id: id %d, last id %d\n", | ||||
id, nbp->nb_last_id); | id, nbp->nb_last_id); | ||||
#endif | #endif | ||||
return; | return (EINVAL); | ||||
} | } | ||||
/* Will store this substring in a WIN_CHARS-aligned slot. */ | /* Will store this substring in a WIN_CHARS-aligned slot. */ | ||||
slot = &nbp->nb_buf[id * WIN_CHARS]; | slot = &nbp->nb_buf[id * WIN_CHARS]; | ||||
count = strlen(name); | count = strlen(name); | ||||
newlen = nbp->nb_len + count; | newlen = nbp->nb_len + count; | ||||
if (newlen > WIN_MAXLEN || newlen > MAXNAMLEN) { | if (newlen > WIN_MAXLEN || newlen > MAXNAMLEN) { | ||||
#ifdef MSDOSFS_DEBUG | #ifdef MSDOSFS_DEBUG | ||||
printf("msdosfs: file name length %zu too large\n", newlen); | printf("msdosfs: file name length %zu too large\n", newlen); | ||||
#endif | #endif | ||||
return; | return (ENAMETOOLONG); | ||||
} | } | ||||
/* Shift suffix upwards by the amount length exceeds WIN_CHARS. */ | /* Shift suffix upwards by the amount length exceeds WIN_CHARS. */ | ||||
if (count > WIN_CHARS && nbp->nb_len != 0) | if (count > WIN_CHARS && nbp->nb_len != 0) { | ||||
if ((id * WIN_CHARS + count + nbp->nb_len) > | |||||
sizeof(nbp->nb_buf)) | |||||
return (ENAMETOOLONG); | |||||
bcopy(slot + WIN_CHARS, slot + count, nbp->nb_len); | bcopy(slot + WIN_CHARS, slot + count, nbp->nb_len); | ||||
} | |||||
/* Copy in the substring to its slot and update length so far. */ | /* Copy in the substring to its slot and update length so far. */ | ||||
bcopy(name, slot, count); | bcopy(name, slot, count); | ||||
nbp->nb_len = newlen; | nbp->nb_len = newlen; | ||||
nbp->nb_last_id = id; | nbp->nb_last_id = id; | ||||
return (0); | |||||
} | } | ||||
/* | /* | ||||
* Take the completed string and use it to setup the struct dirent. | * Take the completed string and use it to setup the struct dirent. | ||||
* Be sure to always nul-terminate the d_name and then copy the string | * Be sure to always nul-terminate the d_name and then copy the string | ||||
* from our buffer. Note that this function assumes the full string has | * from our buffer. Note that this function assumes the full string has | ||||
* been reassembled in the buffer. If it's called before all substrings | * been reassembled in the buffer. If it's called before all substrings | ||||
* have been written via mbnambuf_write(), the result will be incorrect. | * have been written via mbnambuf_write(), the result will be incorrect. | ||||
Show All 16 Lines |