00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00069 #include <fs/phatfs.h>
00070 #include <fs/phatvol.h>
00071 #include <fs/phatdir.h>
00072 #include <fs/phatutil.h>
00073
00074 #include <stdlib.h>
00075 #include <string.h>
00076 #include <time.h>
00077 #include <ctype.h>
00078 #include <errno.h>
00079
00080 #if 0
00081
00082 #define NUTDEBUG
00083 #include <stdio.h>
00084 #include <fs/phatdbg.h>
00085 #endif
00086
00091
00098 void GetDosTimeStamp(uint16_t * dostim, uint16_t * dosdat)
00099 {
00100 time_t now;
00101 struct _tm *gmt;
00102
00103 time(&now);
00104 gmt = localtime(&now);
00105
00106 if (dosdat) {
00107 *dosdat = (uint16_t) (gmt->tm_mday | ((gmt->tm_mon + 1) << 5) | ((gmt->tm_year - 80) << 9));
00108 }
00109 if (dostim) {
00110 *dostim = (uint16_t) ((gmt->tm_sec / 2) | (gmt->tm_min << 5) | (gmt->tm_hour << 11));
00111 }
00112 }
00113
00123 int MakePhatName(CONST char *src, uint8_t * dst)
00124 {
00125 int rc = 0;
00126 int i;
00127
00128
00129 memset(dst, ' ', 11);
00130
00131
00132 for (i = 0; src[i] == '.'; i++);
00133
00134 if (src[i] == 0 && (i == 1 || i == 2)) {
00135 while (i--) {
00136 *dst++ = '.';
00137 }
00138 return 0;
00139 }
00140
00141
00142 if (*src == (char)PHAT_REM_DIRENT) {
00143 dst[0] = PHAT_REM_NAMENT;
00144 src++;
00145 } else {
00146 dst[0] = toupper(*src);
00147 src++;
00148 }
00149
00150
00151 for (i = 1; i < 8 && *src && *src != '.'; i++, src++) {
00152 dst[i] = toupper(*src);
00153 }
00154
00155
00156 if (*src) {
00157
00158 if (*src != '.') {
00159 return -1;
00160 }
00161
00162 src++;
00163 for (i = 8; i < 11 && *src; i++, src++) {
00164 dst[i] = toupper(*src);
00165 }
00166
00167 if (*src) {
00168 return -1;
00169 }
00170 }
00171
00172
00173 for (i = 0; i < 11; i++) {
00174
00175 if (dst[i] < ' ') {
00176 return -1;
00177 }
00178
00179 if (strchr("\"+,./:;<=>[\\]^", dst[i])) {
00180 return -1;
00181 }
00182
00183 if (dst[i] == '?') {
00184 rc = 1;
00185 } else if (dst[i] == '*') {
00186 rc = 1;
00187
00188
00189 if (i < 8) {
00190 memset(&dst[i], '?', 8 - i);
00191 } else {
00192 memset(&dst[i], '?', 11 - i);
00193 }
00194 }
00195 }
00196 return rc;
00197 }
00198
00208 void MakeVisibleName(CONST uint8_t * src, char *dst)
00209 {
00210 int i;
00211
00212
00213 if (src[0] == PHAT_REM_NAMENT) {
00214 *dst++ = PHAT_REM_DIRENT;
00215 } else {
00216 *dst++ = src[0];
00217 }
00218
00219
00220 for (i = 1; i < 8 && src[i] != ' '; i++) {
00221 *dst++ = src[i];
00222 }
00223
00224
00225 for (i = 8; i < 11 && src[i] != ' '; i++) {
00226 if (i == 8) {
00227 *dst++ = '.';
00228 }
00229 *dst++ = src[i];
00230 }
00231 *dst = 0;
00232 }
00233
00245 char *GetParentPath(CONST char *path, CONST char **comp)
00246 {
00247 char *parent;
00248 int len;
00249
00250 if ((*comp = strrchr(path, '/')) == NULL) {
00251 errno = EINVAL;
00252 return NULL;
00253 }
00254
00255 (*comp)++;
00256 len = strlen(path) - strlen(*comp);
00257 if (len < 2) {
00258 len = 2;
00259 }
00260 if ((parent = malloc(len)) == NULL) {
00261 return NULL;
00262 }
00263 memcpy(parent, (void *)path, len - 1);
00264 parent[len - 1] = 0;
00265
00266 return parent;
00267 }
00268
00276 int IsFixedRootDir(NUTFILE * ndp)
00277 {
00278 NUTDEVICE *dev = ndp->nf_dev;
00279 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00280 PHATFILE *fcb;
00281
00282
00283 if (vol->vol_type == 32) {
00284 return 0;
00285 }
00286
00287
00288 fcb = ndp->nf_fcb;
00289 if (fcb->f_de_sect || fcb->f_dirent.dent_clusthi || fcb->f_dirent.dent_clust) {
00290 return 0;
00291 }
00292 return 1;
00293 }
00294
00300 void PhatFilePosRewind(PHATFILE * fcb)
00301 {
00302
00303 fcb->f_pos = 0;
00304
00305 fcb->f_clust = fcb->f_dirent.dent_clusthi;
00306 fcb->f_clust <<= 16;
00307 fcb->f_clust += fcb->f_dirent.dent_clust;
00308
00309 fcb->f_clust_pos = 0;
00310
00311 fcb->f_sect_pos = 0;
00312 }
00313
00325 int PhatFilePosSet(NUTFILE * nfp, uint32_t pos)
00326 {
00327 uint32_t dist;
00328 uint32_t step;
00329 uint32_t clust;
00330 PHATFILE *fcb = nfp->nf_fcb;
00331 NUTDEVICE *dev = nfp->nf_dev;
00332 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00333
00334
00335 if (pos == 0) {
00336 PhatFilePosRewind(fcb);
00337 return 0;
00338 }
00339
00340
00341 if ((fcb->f_dirent.dent_attr & PHAT_FATTR_DIR) == 0 && pos > fcb->f_dirent.dent_fsize) {
00342 return -1;
00343 }
00344
00345
00346
00347
00348
00349
00350 if (pos < fcb->f_pos) {
00351 PhatFilePosRewind(fcb);
00352 dist = pos;
00353 } else {
00354 dist = pos - fcb->f_pos;
00355 }
00356
00357 for (;;) {
00358 if (fcb->f_sect_pos >= vol->vol_sectsz) {
00359 if (IsFixedRootDir(nfp)) {
00360 if (fcb->f_clust_pos + 1 >= vol->vol_rootsz) {
00361
00362 break;
00363 }
00364 fcb->f_clust_pos++;
00365 }
00366 else {
00367
00368
00369
00370
00371
00372 if (fcb->f_clust_pos + 1 >= vol->vol_clustsz) {
00373
00374
00375
00376
00377 if (vol->vol_type == 32) {
00378 if (Phat32GetClusterLink(dev, fcb->f_clust, &clust)) {
00379 break;
00380 }
00381 if (clust >= (PHATEOC & PHAT32CMASK)) {
00382 break;
00383 }
00384 } else if (vol->vol_type == 16) {
00385 if (Phat16GetClusterLink(dev, fcb->f_clust, &clust)) {
00386 break;
00387 }
00388 if (clust >= (PHATEOC & PHAT16CMASK)) {
00389 break;
00390 }
00391 } else if (Phat12GetClusterLink(dev, fcb->f_clust, &clust)) {
00392 break;
00393 }
00394 else if (clust >= (PHATEOC & PHAT12CMASK)) {
00395 break;
00396 }
00397 fcb->f_clust_pos = 0;
00398 fcb->f_clust_prv = fcb->f_clust;
00399 fcb->f_clust = clust;
00400 } else {
00401 fcb->f_clust_pos++;
00402 }
00403 }
00404 fcb->f_sect_pos = 0;
00405 }
00406 if (dist == 0) {
00407 break;
00408 }
00409
00410
00411 step = vol->vol_sectsz - fcb->f_sect_pos;
00412 if (step > dist) {
00413 step = dist;
00414 }
00415 fcb->f_sect_pos += step;
00416 fcb->f_pos += step;
00417 dist -= step;
00418 }
00419 return fcb->f_pos == pos ? 0 : -1;
00420 }
00421