/** * Entfernt eine Datei * \param *filename Dateiname * \param *buffer Puffer fuer mindestens BOTFS_BLOCK_SIZE Byte * \return 0, falls kein Fehler */ int8_t botfs_unlink(const char * filename, void * buffer) { botfs_acquire_lock_low(&botfs_mutex); /* Datei suchen */ botfs_file_t * ptr = search_file(filename, buffer); if (ptr == NULL) { botfs_release_lock_low(&botfs_mutex); PRINT_MSG("botfs_unlink(): Datei nicht vorhanden"); return -1; } /* Root-Dir Eintrag loeschen */ ptr->name[0] = 0; ptr->name[1] = 0; botfs_seek(&botfs_vol_data.rootdir, -1, SEEK_CUR); // Dateizeiger stand auf naechstem Dir-Block => -1 if (botfs_write(&botfs_vol_data.rootdir, buffer) != 0) { botfs_release_lock_low(&botfs_mutex); PRINT_MSG("botfs_unlink(): Fehler beim Schreiben des Root-Blocks"); return -2; } const uint16_t start = ptr->descr.start; const uint16_t end = ptr->descr.end; /* Freelist aktualisieren */ int8_t res = add_to_freelist(start, end, buffer); botfs_release_lock_low(&botfs_mutex); PRINT_MSG("botfs_unlink(): Datei \"%s\" wurde geloescht", filename); return res; }
static int verify_disklabel(struct fdisk_context *cxt, int verbose) { int Index[SGI_MAXPARTITIONS]; /* list of valid partitions */ int sortcount = 0; /* number of used partitions, i.e. non-zero lengths */ int entire = 0, i = 0; unsigned int start = 0; long long gap = 0; /* count unused blocks */ unsigned int lastblock = sgi_get_lastblock(cxt); assert(cxt); assert(cxt->label); assert(fdisk_is_disklabel(cxt, SGI)); clear_freelist(cxt); memset(Index, 0, sizeof(Index)); for (i=0; i < SGI_MAXPARTITIONS; i++) { if (sgi_get_num_sectors(cxt, i) != 0) { Index[sortcount++] = i; if (sgi_get_sysid(cxt, i) == SGI_TYPE_ENTIRE_DISK && entire++ == 1) { if (verbose) fdisk_info(cxt, _("More than one entire " "disk entry present.")); } } } if (sortcount == 0) { if (verbose) fdisk_info(cxt, _("No partitions defined")); return (lastblock > 0) ? 1 : (lastblock == 0) ? 0 : -1; } sort(Index, sortcount, sizeof(Index[0]), cxt, compare_start); if (sgi_get_sysid(cxt, Index[0]) == SGI_TYPE_ENTIRE_DISK) { if (verbose && Index[0] != 10) fdisk_info(cxt, _("IRIX likes when Partition 11 " "covers the entire disk.")); if (verbose && sgi_get_start_sector(cxt, Index[0]) != 0) fdisk_info(cxt, _("The entire disk partition should " "start at block 0, not at diskblock %d."), sgi_get_start_sector(cxt, Index[0])); if (verbose && sgi_get_num_sectors(cxt, Index[0]) != lastblock) DBG(LABEL, dbgprint( "entire disk partition=%ds, but disk=%ds", sgi_get_num_sectors(cxt, Index[0]), lastblock)); lastblock = sgi_get_num_sectors(cxt, Index[0]); } else if (verbose) { fdisk_info(cxt, _("Partition 11 should cover the entire disk.")); DBG(LABEL, dbgprint("sysid=%d\tpartition=%d", sgi_get_sysid(cxt, Index[0]), Index[0]+1)); } for (i=1, start=0; i<sortcount; i++) { int cylsize = sgi_get_nsect(cxt) * sgi_get_ntrks(cxt); if (verbose && cylsize && (sgi_get_start_sector(cxt, Index[i]) % cylsize) != 0) DBG(LABEL, dbgprint("partition %d does not start on " "cylinder boundary.", Index[i]+1)); if (verbose && cylsize && sgi_get_num_sectors(cxt, Index[i]) % cylsize != 0) DBG(LABEL, dbgprint("partition %d does not end on " "cylinder boundary.", Index[i]+1)); /* We cannot handle several "entire disk" entries. */ if (sgi_get_sysid(cxt, Index[i]) == SGI_TYPE_ENTIRE_DISK) continue; if (start > sgi_get_start_sector(cxt, Index[i])) { if (verbose) fdisk_info(cxt, _("The Partition %d and %d overlap " "by %d sectors."), Index[i-1]+1, Index[i]+1, start - sgi_get_start_sector(cxt, Index[i])); if (gap > 0) gap = -gap; if (gap == 0) gap = -1; } if (start < sgi_get_start_sector(cxt, Index[i])) { if (verbose) fdisk_info(cxt, _("Unused gap of %8u sectors " "- sectors %8u-%u"), sgi_get_start_sector(cxt, Index[i]) - start, start, sgi_get_start_sector(cxt, Index[i])-1); gap += sgi_get_start_sector(cxt, Index[i]) - start; add_to_freelist(cxt, start, sgi_get_start_sector(cxt, Index[i])); } start = sgi_get_start_sector(cxt, Index[i]) + sgi_get_num_sectors(cxt, Index[i]); /* Align free space on cylinder boundary */ if (cylsize && start % cylsize) start += cylsize - (start % cylsize); DBG(LABEL, dbgprint("%2d:%12d\t%12d\t%12d", Index[i], sgi_get_start_sector(cxt, Index[i]), sgi_get_num_sectors(cxt, Index[i]), sgi_get_sysid(cxt, Index[i]))); } if (start < lastblock) { if (verbose) fdisk_info(cxt, _("Unused gap of %8u sectors - sectors %8u-%u"), lastblock - start, start, lastblock-1); gap += lastblock - start; add_to_freelist(cxt, start, lastblock); } /* * Done with arithmetics. Go for details now */ if (verbose) { if (sgi_get_bootpartition(cxt) < 0 || !sgi_get_num_sectors(cxt, sgi_get_bootpartition(cxt))) fdisk_info(cxt, _("The boot partition does not exist.")); if (sgi_get_swappartition(cxt) < 0 || !sgi_get_num_sectors(cxt, sgi_get_swappartition(cxt))) fdisk_info(cxt, _("The swap partition does not exist.")); else if (sgi_get_sysid(cxt, sgi_get_swappartition(cxt)) != SGI_TYPE_SWAP && sgi_get_sysid(cxt, sgi_get_swappartition(cxt)) != MBR_LINUX_SWAP_PARTITION) fdisk_info(cxt, _("The swap partition has no swap type.")); if (sgi_check_bootfile(cxt, "/unix")) fdisk_info(cxt, _("You have chosen an unusual boot " "file name.")); } return (gap > 0) ? 1 : (gap == 0) ? 0 : -1; }
/** * Legt eine neue Datei an * \param *filename Dateiname * \param size Groesse der Datei in Bloecken * \param alignment Ausrichtung des Dateianfangs an einer X-Blockgrenze (normalerweise 0) * \param *buffer Puffer fuer mindestens BOTFS_BLOCK_SIZE Byte * \return 0, falls kein Fehler */ int8_t botfs_create(const char * filename, uint16_t size, uint16_t alignment, void * buffer) { botfs_acquire_lock_low(&botfs_mutex); /* Datei bereits vorhanden? */ if (search_file(filename, buffer) != NULL) { botfs_release_lock_low(&botfs_mutex); PRINT_MSG("botfs_create(): file existing"); return -1; } ++size; // Header braucht einen Block PRINT_MSG("botfs_create(): creating file \"%s\" with size 0x%x blocks", filename, size); alignment = alignment > 0 ? alignment - 1 : 0; /* freien Speicherbereich suchen */ botfs_freelist_entry_t * pFree = search_freelist(test_size, size + alignment, 1, buffer); if (pFree == NULL) { botfs_release_lock_low(&botfs_mutex); PRINT_MSG("botfs_create(): no space left"); return -2; } PRINT_MSG("botfs_create(): pFree->block=0x%x", pFree->block); PRINT_MSG("botfs_create(): sector=0x%x", get_sector(pFree->block)); /* Alignment des ersten Datenblocks berechnen */ uint16_t offset = (uint16_t) (((get_sector(pFree->block + BOTFS_HEADER_SIZE) + alignment) & ~alignment) - get_sector(pFree->block + BOTFS_HEADER_SIZE)); PRINT_MSG("botfs_create(): alignment-offset=0x%x", offset); /* Freelist aktualisieren */ pFree->size -= size + offset; uint16_t start = pFree->block + offset; PRINT_MSG("botfs_create(): start=0x%x", start); PRINT_MSG("botfs_create(): first_data=0x%x", start + BOTFS_HEADER_SIZE); pFree->block += size + offset; uint16_t end = pFree->block - 1; PRINT_MSG("botfs_create(): end=0x%x", end); /* Freelist-Block zurueckschreiben */ botfs_seek(&botfs_vol_data.freelist, -1, SEEK_CUR); if (botfs_write(&botfs_vol_data.freelist, buffer) != 0) { botfs_release_lock_low(&botfs_mutex); PRINT_MSG("botfs_create(): can't write freelist"); return -3; } /* Alingment-Offset als frei markieren */ if (offset != 0) { PRINT_MSG("botfs_create(): freeing 0x%x - 0x%x", start - offset, start - 1); if (add_to_freelist(start - offset, start - 1, buffer) != 0) { botfs_release_lock_low(&botfs_mutex); PRINT_MSG("botfs_create(): can't update freelist"); // Freelist muesste man hier eigentlich wieder zuruecksetzen return -4; } } /* leeren Root-Dir-Eintrag suchen */ botfs_file_t * pFile = search_file("", buffer); if (pFile == NULL) { botfs_release_lock_low(&botfs_mutex); PRINT_MSG("botfs_create(): no dir-entry left"); // Freelist muesste man hier eigentlich wieder zuruecksetzen return -4; } char * ptr = pFile->name; if (filename[0] != '/') { *ptr = '/'; ptr++; } strncpy(ptr, filename, BOTFS_MAX_FILENAME - 1); pFile->descr.start = start; pFile->descr.end = end; /* Root-Dir-Block zurueckschreiben */ botfs_seek(&botfs_vol_data.rootdir, -1, SEEK_CUR); if (botfs_write(&botfs_vol_data.rootdir, buffer) != 0) { botfs_release_lock_low(&botfs_mutex); PRINT_MSG("botfs_create(): can't write rootdir"); // Freelist muesste man hier eigentlich wieder zuruecksetzen return -5; } /* Datei-Header erzeugen */ botfs_file_header_t * pHeader = buffer; memset(pHeader, 0, sizeof(botfs_file_header_t)); /* Datei als komplett belegt kennzeichnen */ pHeader->used_blocks.start = start + BOTFS_HEADER_SIZE; pHeader->used_blocks.end = end; pHeader->used_blocks.bytes_last_block = BOTFS_BLOCK_SIZE; PRINT_MSG("botfs_create(): writing file-header..."); if (botfs_write_low(start, buffer) != 0) { botfs_release_lock_low(&botfs_mutex); PRINT_MSG("botfs_create(): can't write file-header"); // Freelist muesste man hier eigentlich wieder zuruecksetzen return -6; } botfs_release_lock_low(&botfs_mutex); return 0; }