Go to the documentation of this file.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
00072 #include <fs/phatfs.h>
00073 #include <fs/phatvol.h>
00074 #include <fs/phatdir.h>
00075 #include <fs/phatutil.h>
00076
00077 #include <stdlib.h>
00078 #include <string.h>
00079 #include <time.h>
00080 #include <ctype.h>
00081 #include <errno.h>
00082 #include <memdebug.h>
00083
00084 #if 0
00085
00086 #define NUTDEBUG
00087 #include <stdio.h>
00088 #include <fs/phatdbg.h>
00089 #endif
00090
00095
00102 void GetDosTimeStamp(uint16_t * dostim, uint16_t * dosdat)
00103 {
00104 time_t now;
00105 struct _tm *gmt;
00106
00107 time(&now);
00108 gmt = localtime(&now);
00109
00110 if (dosdat) {
00111 *dosdat = (uint16_t) (gmt->tm_mday | ((gmt->tm_mon + 1) << 5) | ((gmt->tm_year - 80) << 9));
00112 }
00113 if (dostim) {
00114 *dostim = (uint16_t) ((gmt->tm_sec / 2) | (gmt->tm_min << 5) | (gmt->tm_hour << 11));
00115 }
00116 }
00117
00127 int MakePhatName(CONST char *src, uint8_t * dst)
00128 {
00129 int rc = 0;
00130 int i;
00131
00132
00133 memset(dst, ' ', 11);
00134
00135
00136 for (i = 0; src[i] == '.'; i++);
00137
00138 if (src[i] == 0 && (i == 1 || i == 2)) {
00139 while (i--) {
00140 *dst++ = '.';
00141 }
00142 return 0;
00143 }
00144
00145
00146 if (*src == (char)PHAT_REM_DIRENT) {
00147 dst[0] = PHAT_REM_NAMENT;
00148 src++;
00149 } else {
00150 dst[0] = toupper((unsigned char)*src);
00151 src++;
00152 }
00153
00154
00155 for (i = 1; i < 8 && *src && *src != '.'; i++, src++) {
00156 dst[i] = toupper((unsigned char)*src);
00157 }
00158
00159
00160 if (*src) {
00161
00162 if (*src != '.') {
00163 return -1;
00164 }
00165
00166 src++;
00167 for (i = 8; i < 11 && *src; i++, src++) {
00168 dst[i] = toupper((unsigned char)*src);
00169 }
00170
00171 if (*src) {
00172 return -1;
00173 }
00174 }
00175
00176
00177 for (i = 0; i < 11; i++) {
00178
00179 if (dst[i] < ' ') {
00180 return -1;
00181 }
00182
00183 if (strchr("\"+,./:;<=>[\\]^", dst[i])) {
00184 return -1;
00185 }
00186
00187 if (dst[i] == '?') {
00188 rc = 1;
00189 } else if (dst[i] == '*') {
00190 rc = 1;
00191
00192
00193 if (i < 8) {
00194 memset(&dst[i], '?', 8 - i);
00195 } else {
00196 memset(&dst[i], '?', 11 - i);
00197 }
00198 }
00199 }
00200 return rc;
00201 }
00202
00212 void MakeVisibleName(CONST uint8_t * src, char *dst)
00213 {
00214 int i;
00215
00216
00217 if (src[0] == PHAT_REM_NAMENT) {
00218 *dst++ = PHAT_REM_DIRENT;
00219 } else {
00220 *dst++ = src[0];
00221 }
00222
00223
00224 for (i = 1; i < 8 && src[i] != ' '; i++) {
00225 *dst++ = src[i];
00226 }
00227
00228
00229 for (i = 8; i < 11 && src[i] != ' '; i++) {
00230 if (i == 8) {
00231 *dst++ = '.';
00232 }
00233 *dst++ = src[i];
00234 }
00235 *dst = 0;
00236 }
00237
00249 char *GetParentPath(CONST char *path, CONST char **comp)
00250 {
00251 char *parent;
00252 int len;
00253
00254 if ((*comp = strrchr(path, '/')) == NULL) {
00255 errno = EINVAL;
00256 return NULL;
00257 }
00258
00259 (*comp)++;
00260 len = strlen(path) - strlen(*comp);
00261 if (len < 2) {
00262 len = 2;
00263 }
00264 if ((parent = malloc(len)) == NULL) {
00265 return NULL;
00266 }
00267 memcpy(parent, (void *)path, len - 1);
00268 parent[len - 1] = 0;
00269
00270 return parent;
00271 }
00272
00280 int IsFixedRootDir(NUTFILE * ndp)
00281 {
00282 NUTDEVICE *dev = ndp->nf_dev;
00283 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00284 PHATFILE *fcb;
00285
00286
00287 if (vol->vol_type == 32) {
00288 return 0;
00289 }
00290
00291
00292 fcb = ndp->nf_fcb;
00293 if (fcb->f_de_sect || fcb->f_dirent.dent_clusthi || fcb->f_dirent.dent_clust) {
00294 return 0;
00295 }
00296 return 1;
00297 }
00298
00304 void PhatFilePosRewind(PHATFILE * fcb)
00305 {
00306
00307 fcb->f_pos = 0;
00308
00309 fcb->f_clust = fcb->f_dirent.dent_clusthi;
00310 fcb->f_clust <<= 16;
00311 fcb->f_clust += fcb->f_dirent.dent_clust;
00312
00313 fcb->f_clust_pos = 0;
00314
00315 fcb->f_sect_pos = 0;
00316 }
00317
00329 int PhatFilePosSet(NUTFILE * nfp, uint32_t pos)
00330 {
00331 uint32_t dist;
00332 uint32_t step;
00333 uint32_t clust;
00334 PHATFILE *fcb = nfp->nf_fcb;
00335 NUTDEVICE *dev = nfp->nf_dev;
00336 PHATVOL *vol = (PHATVOL *) dev->dev_dcb;
00337
00338
00339 if (pos == 0) {
00340 PhatFilePosRewind(fcb);
00341 return 0;
00342 }
00343
00344
00345 if ((fcb->f_dirent.dent_attr & PHAT_FATTR_DIR) == 0 && pos > fcb->f_dirent.dent_fsize) {
00346 return -1;
00347 }
00348
00349
00350
00351
00352
00353
00354 if (pos < fcb->f_pos) {
00355 PhatFilePosRewind(fcb);
00356 dist = pos;
00357 } else {
00358 dist = pos - fcb->f_pos;
00359 }
00360
00361 for (;;) {
00362 if (fcb->f_sect_pos >= vol->vol_sectsz) {
00363 if (IsFixedRootDir(nfp)) {
00364 if (fcb->f_clust_pos + 1 >= vol->vol_rootsz) {
00365
00366 break;
00367 }
00368 fcb->f_clust_pos++;
00369 }
00370 else {
00371
00372
00373
00374
00375
00376 if (fcb->f_clust_pos + 1 >= vol->vol_clustsz) {
00377
00378
00379
00380
00381 if (vol->vol_type == 32) {
00382 if (Phat32GetClusterLink(dev, fcb->f_clust, &clust)) {
00383 break;
00384 }
00385 if (clust >= (PHATEOC & PHAT32CMASK)) {
00386 break;
00387 }
00388 } else if (vol->vol_type == 16) {
00389 if (Phat16GetClusterLink(dev, fcb->f_clust, &clust)) {
00390 break;
00391 }
00392 if (clust >= (PHATEOC & PHAT16CMASK)) {
00393 break;
00394 }
00395 } else if (Phat12GetClusterLink(dev, fcb->f_clust, &clust)) {
00396 break;
00397 }
00398 else if (clust >= (PHATEOC & PHAT12CMASK)) {
00399 break;
00400 }
00401 fcb->f_clust_pos = 0;
00402 fcb->f_clust_prv = fcb->f_clust;
00403 fcb->f_clust = clust;
00404 } else {
00405 fcb->f_clust_pos++;
00406 }
00407 }
00408 fcb->f_sect_pos = 0;
00409 }
00410 if (dist == 0) {
00411 break;
00412 }
00413
00414
00415 step = vol->vol_sectsz - fcb->f_sect_pos;
00416 if (step > dist) {
00417 step = dist;
00418 }
00419 fcb->f_sect_pos += step;
00420 fcb->f_pos += step;
00421 dist -= step;
00422 }
00423 return fcb->f_pos == pos ? 0 : -1;
00424 }
00425