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