void printFat(Stream_t *Stream) { File_t *This = getUnbufferedFile(Stream); unsigned long n; int rel; unsigned long begin, end; int first; n = This->FirstAbsCluNr; if(!n) { printf("Root directory or empty file\n"); return; } rel = 0; first = 1; begin = end = 0; do { if (first || n != end+1) { if (!first) { if (begin != end) printf("-%lu", end); printf("> "); } begin = end = n; printf("<%lu", begin); } else { end++; } first = 0; n = fatDecode(This->Fs, n); rel++; if(loopDetect(This, rel, n) < 0) n = 1; } while (n <= This->Fs->last_fat && n != 1); if(!first) { if (begin != end) printf("-%lu", end); printf(">"); } }
static int normal_map(File_t *This, off_t where, size_t *len, int mode, mt_off_t *res) { int offset; off_t end; int NrClu; /* number of clusters to read */ unsigned int RelCluNr; unsigned int CurCluNr; unsigned int NewCluNr; unsigned int AbsCluNr; int clus_size; Fs_t *Fs = This->Fs; *res = 0; clus_size = Fs->cluster_size * Fs->sector_size; offset = where % clus_size; if (mode == MT_READ) maximize(*len, This->FileSize - where); if (*len == 0 ) return 0; if (This->FirstAbsCluNr < 2){ if( mode == MT_READ || *len == 0){ *len = 0; return 0; } NewCluNr = get_next_free_cluster(This->Fs, 1); if (NewCluNr == 1 ){ errno = ENOSPC; return -2; } hash_remove(filehash, (void *) This, This->hint); This->FirstAbsCluNr = NewCluNr; hash_add(filehash, (void *) This, &This->hint); fatAllocate(This->Fs, NewCluNr, Fs->end_fat); } RelCluNr = where / clus_size; if (RelCluNr >= This->PreviousRelCluNr){ CurCluNr = This->PreviousRelCluNr; AbsCluNr = This->PreviousAbsCluNr; } else { CurCluNr = 0; AbsCluNr = This->FirstAbsCluNr; } NrClu = (offset + *len - 1) / clus_size; while (CurCluNr <= RelCluNr + NrClu){ if (CurCluNr == RelCluNr){ /* we have reached the beginning of our zone. Save * coordinates */ This->PreviousRelCluNr = RelCluNr; This->PreviousAbsCluNr = AbsCluNr; } NewCluNr = fatDecode(This->Fs, AbsCluNr); if (NewCluNr == 1 || NewCluNr == 0){ fprintf(stderr,"Fat problem while decoding %d %x\n", AbsCluNr, NewCluNr); exit(1); } if(CurCluNr == RelCluNr + NrClu) break; if (NewCluNr > Fs->last_fat && mode == MT_WRITE){ /* if at end, and writing, extend it */ NewCluNr = get_next_free_cluster(This->Fs, AbsCluNr); if (NewCluNr == 1 ){ /* no more space */ errno = ENOSPC; return -2; } fatAppend(This->Fs, AbsCluNr, NewCluNr); } if (CurCluNr < RelCluNr && NewCluNr > Fs->last_fat){ *len = 0; return 0; } if (CurCluNr >= RelCluNr && NewCluNr != AbsCluNr + 1) break; CurCluNr++; AbsCluNr = NewCluNr; if(loopDetect(This, CurCluNr, AbsCluNr)) { errno = EIO; return -2; } } maximize(*len, (1 + CurCluNr - RelCluNr) * clus_size - offset); end = where + *len; if(batchmode && mode == MT_WRITE && end >= This->FileSize) { *len += ROUND_UP(end, clus_size) - end; } if((*len + offset) / clus_size + This->PreviousAbsCluNr-2 > Fs->num_clus) { fprintf(stderr, "cluster too big\n"); exit(1); } *res = sectorsToBytes((Stream_t*)Fs, (This->PreviousAbsCluNr-2) * Fs->cluster_size + Fs->clus_start) + offset; return 1; }
int assemble(struct membuf *source, struct membuf *dest) { struct vec guesses_history[1]; struct map guesses_storage[1]; int dest_pos; int result; dump_sym_table(LOG_DEBUG, s->initial_symbols); vec_init(guesses_history, sizeof(struct map)); s->guesses = NULL; dest_pos = membuf_memlen(dest); for(;;) { map_put_all(s->sym_table, s->initial_symbols); named_buffer_copy(s->named_buffer, s->initial_named_buffer); map_init(guesses_storage); if(s->guesses != NULL) { /* copy updated guesses from latest pass */ map_put_all(guesses_storage, s->guesses); } s->guesses = guesses_storage; result = assembleSinglePass(source, dest); if(result != 0) { /* the assemble pass failed */ break; } /* check if any guessed symbols was wrong and update them * to their actual value */ if(wasFinalPass()) { /* The assemble pass succeeded without any wrong guesses, * we're done */ break; } if(loopDetect(guesses_history)) { /* More passes would only get us into a loop */ LOG(LOG_VERBOSE, ("Aborting due to loop.\n")); result = -1; break; } LOG(LOG_VERBOSE, ("Trying another pass.\n")); /* allocate storage for the guesses in the history vector */ s->guesses = vec_push(guesses_history, s->guesses); parse_reset(); membuf_truncate(dest, dest_pos); } map_free(guesses_storage); vec_free(guesses_history, (cb_free*)map_free); s->guesses = NULL; return result; }