summaryrefslogtreecommitdiff
path: root/lib/libdisk/chunk.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libdisk/chunk.c')
-rw-r--r--lib/libdisk/chunk.c433
1 files changed, 0 insertions, 433 deletions
diff --git a/lib/libdisk/chunk.c b/lib/libdisk/chunk.c
deleted file mode 100644
index 906911aa8023..000000000000
--- a/lib/libdisk/chunk.c
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * ----------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
- * ----------------------------------------------------------------------------
- *
- * $Id: chunk.c,v 1.14.2.2 1995/06/05 02:24:25 jkh Exp $
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <err.h>
-#include "libdisk.h"
-
-#define new_chunk() memset(malloc(sizeof(struct chunk)), 0, sizeof(struct chunk))
-
-/* Is c2 completely inside c1 ? */
-
-static int
-Chunk_Inside(struct chunk *c1, struct chunk *c2)
-{
- /* if c1 ends before c2 do */
- if (c1->end < c2->end)
- return 0;
- /* if c1 starts after c2 do */
- if (c1->offset > c2->offset)
- return 0;
- return 1;
-}
-
-struct chunk *
-Find_Mother_Chunk(struct chunk *chunks, u_long offset, u_long end, chunk_e type)
-{
- struct chunk *c1,*c2,ct;
- ct.offset = offset;
- ct.end = end;
- switch (type) {
- case whole:
- if (Chunk_Inside(chunks,&ct))
- return chunks;
- case extended:
- for(c1=chunks->part;c1;c1=c1->next) {
- if (c1->type != type)
- continue;
- if (Chunk_Inside(c1,&ct))
- return c1;
- }
- return 0;
- case freebsd:
- for(c1=chunks->part;c1;c1=c1->next) {
- if (c1->type == type)
- if (Chunk_Inside(c1,&ct))
- return c1;
- if (c1->type != extended)
- continue;
- for(c2=c1->part;c2;c2=c2->next)
- if (c2->type == type
- && Chunk_Inside(c2,&ct))
- return c2;
- }
- return 0;
- default:
- warn("Unsupported mother (0x%x) in Find_Mother_Chunk");
- return 0;
- }
-}
-
-void
-Free_Chunk(struct chunk *c1)
-{
- if(!c1) return;
- if(c1->private && c1->private_free)
- (*c1->private_free)(c1->private);
- if(c1->part)
- Free_Chunk(c1->part);
- if(c1->next)
- Free_Chunk(c1->next);
- free(c1->name);
- free(c1);
-}
-
-struct chunk *
-Clone_Chunk(struct chunk *c1)
-{
- struct chunk *c2;
- if(!c1)
- return 0;
- c2 = new_chunk();
- if (!c2) err(1,"malloc failed");
- *c2 = *c1;
- if (c1->private && c1->private_clone)
- c2->private = c2->private_clone(c2->private);
- c2->name = strdup(c2->name);
- c2->next = Clone_Chunk(c2->next);
- c2->part = Clone_Chunk(c2->part);
- return c2;
-}
-
-int
-Insert_Chunk(struct chunk *c2, u_long offset, u_long size, char *name, chunk_e type, int subtype, u_long flags)
-{
- struct chunk *ct,*cs;
-
- /* We will only insert into empty spaces */
- if (c2->type != unused)
- return __LINE__;
-
- ct = new_chunk();
- if (!ct) err(1,"malloc failed");
- memset(ct,0,sizeof *ct);
- ct->disk = c2->disk;
- ct->offset = offset;
- ct->size = size;
- ct->end = offset + size - 1;
- ct->type = type;
- ct->name = strdup(name);
- ct->subtype = subtype;
- ct->flags = flags;
-
- if (!Chunk_Inside(c2,ct)) {
- Free_Chunk(ct);
- return __LINE__;
- }
-
- if(type==freebsd || type==extended) {
- cs = new_chunk();
- if (!cs) err(1,"malloc failed");
- memset(cs,0,sizeof *cs);
- cs->disk = c2->disk;
- cs->offset = offset;
- cs->size = size;
- cs->end = offset + size - 1;
- cs->type = unused;
- cs->name = strdup("-");
- ct->part = cs;
- }
-
- /* Make a new chunk for any trailing unused space */
- if (c2->end > ct->end) {
- cs = new_chunk();
- if (!cs) err(1,"malloc failed");
- *cs = *c2;
- cs->disk = c2->disk;
- cs->offset = ct->end + 1;
- cs->size = c2->end - ct->end;
- if(c2->name)
- cs->name = strdup(c2->name);
- c2->next = cs;
- c2->size -= c2->end - ct->end;
- c2->end = ct->end;
- }
- /* If no leading unused space just occupy the old chunk */
- if (c2->offset == ct->offset) {
- c2->name = ct->name;
- c2->type = ct->type;
- c2->part = ct->part;
- c2->subtype = ct->subtype;
- c2->flags = ct->flags;
- ct->name = 0;
- ct->part = 0;
- Free_Chunk(ct);
- return 0;
- }
- /* else insert new chunk and adjust old one */
- c2->end = ct->offset - 1;
- c2->size -= ct->size;
- ct->next = c2->next;
- c2->next = ct;
- return 0;
-}
-
-int
-Add_Chunk(struct disk *d, long offset, u_long size, char *name, chunk_e type,
- int subtype, u_long flags)
-{
- struct chunk *c1,*c2,ct;
- u_long end = offset + size - 1;
- ct.offset = offset;
- ct.end = end;
- ct.size = size;
-
- if (type == whole) {
- d->chunks = c1 = new_chunk();
- if (!c1) err(1,"malloc failed");
- memset(c1,0,sizeof *c1);
- c2 = c1->part = new_chunk();
- if (!c2) err(1,"malloc failed");
- memset(c2,0,sizeof *c2);
- c2->disk = c1->disk = d;
- c2->offset = c1->offset = offset;
- c2->size = c1->size = size;
- c2->end = c1->end = end;
- c1->name = strdup(name);
- c2->name = strdup("-");
- c1->type = type;
- c2->type = unused;
- c1->flags = flags;
- c1->subtype = subtype;
- return 0;
- }
- if (type == freebsd)
- subtype = 0xa5;
- c1 = 0;
- if(!c1 && (type == freebsd || type == fat || type == unknown))
- c1 = Find_Mother_Chunk(d->chunks,offset,end,extended);
- if(!c1 && (type == freebsd || type == fat || type == unknown))
- c1 = Find_Mother_Chunk(d->chunks,offset,end,whole);
- if(!c1 && type == extended)
- c1 = Find_Mother_Chunk(d->chunks,offset,end,whole);
- if(!c1 && type == part)
- c1 = Find_Mother_Chunk(d->chunks,offset,end,freebsd);
- if(!c1)
- return __LINE__;
- for(c2=c1->part;c2;c2=c2->next) {
- if (c2->type != unused)
- continue;
- if(Chunk_Inside(c2,&ct)) {
- if (type != freebsd)
- goto doit;
- if (!(flags & CHUNK_ALIGN))
- goto doit;
- if (offset == d->chunks->offset
- && end == d->chunks->end)
- goto doit;
-
- /* Round down to prev cylinder */
- offset = Prev_Cyl_Aligned(d,offset);
- /* Stay inside the parent */
- if (offset < c2->offset)
- offset = c2->offset;
- /* Round up to next cylinder */
- offset = Next_Cyl_Aligned(d,offset);
- /* Keep one track clear in front of parent */
- if (offset == c1->offset)
- offset = Next_Track_Aligned(d,offset+1);
-
- /* Work on the (end+1) */
- size += offset;
- /* Round up to cylinder */
- size = Next_Cyl_Aligned(d,size);
- /* Stay inside parent */
- if ((size-1) > c2->end)
- size = c2->end+1;
- /* Round down to cylinder */
- size = Prev_Cyl_Aligned(d,size);
-
- /* Convert back to size */
- size -= offset;
-
- doit:
- return Insert_Chunk(c2,offset,size,name,
- type,subtype,flags);
- }
- }
- return __LINE__;
-}
-
-char *
-ShowChunkFlags(struct chunk *c)
-{
- static char ret[10];
-
- int i=0;
- if (c->flags & CHUNK_BSD_COMPAT) ret[i++] = 'C';
- if (c->flags & CHUNK_ACTIVE) ret[i++] = 'A';
- if (c->flags & CHUNK_ALIGN) ret[i++] = '=';
- if (c->flags & CHUNK_PAST_1024) ret[i++] = '>';
- if (c->flags & CHUNK_IS_ROOT) ret[i++] = 'R';
- if (c->flags & CHUNK_BAD144) ret[i++] = 'B';
- ret[i++] = '\0';
- return ret;
-}
-
-void
-Print_Chunk(struct chunk *c1,int offset)
-{
- int i;
- if(!c1) return;
- for(i=0;i<offset-2;i++) putchar(' ');
- for(;i<offset;i++) putchar('-');
- putchar('>');
- for(;i<10;i++) putchar(' ');
- printf("%p %8ld %8lu %8lu %-8s %-8s 0x%02x %s",
- c1, c1->offset, c1->size, c1->end, c1->name,
- chunk_n[c1->type],c1->subtype,
- ShowChunkFlags(c1));
- putchar('\n');
- Print_Chunk(c1->part,offset + 2);
- Print_Chunk(c1->next,offset);
-}
-
-void
-Debug_Chunk(struct chunk *c1)
-{
- Print_Chunk(c1,2);
-}
-
-void
-Bios_Limit_Chunk(struct chunk *c1, u_long limit)
-{
- if (c1->part)
- Bios_Limit_Chunk(c1->part,limit);
- if (c1->next)
- Bios_Limit_Chunk(c1->next,limit);
- if (c1->end >= limit) {
- c1->flags |= CHUNK_PAST_1024;
- } else {
- c1->flags &= ~CHUNK_PAST_1024;
- }
-}
-
-int
-Delete_Chunk(struct disk *d, struct chunk *c)
-{
- struct chunk *c1=0,*c2,*c3;
- chunk_e type = c->type;
-
- if(type == whole)
- return 1;
- if(!c1 && (type == freebsd || type == fat || type == unknown))
- c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,extended);
- if(!c1 && (type == freebsd || type == fat || type == unknown))
- c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,whole);
- if(!c1 && type == extended)
- c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,whole);
- if(!c1 && type == part)
- c1 = Find_Mother_Chunk(d->chunks,c->offset,c->end,freebsd);
- if(!c1)
- return 1;
- for(c2=c1->part;c2;c2=c2->next) {
- if (c2 == c) {
- c2->type = unused;
- c2->subtype = 0;
- c2->flags = 0;
- free(c2->name);
- c2->name = strdup("-");
- Free_Chunk(c2->part);
- c2->part =0;
- goto scan;
- }
- }
- return 1;
- scan:
- for(c2=c1->part;c2;c2=c2->next) {
- if (c2->type != unused)
- continue;
- if (!c2->next)
- continue;
- if (c2->next->type != unused)
- continue;
- c3 = c2->next;
- c2->size += c3->size;
- c2->end = c3->end;
- c2->next = c3->next;
- c3->next = 0;
- Free_Chunk(c3);
- goto scan;
- }
- Fixup_Names(d);
- return 0;
-}
-
-#if 0
-int
-Collapse_Chunk(struct disk *d, struct chunk *c1)
-{
- struct chunk *c2, *c3;
-
- if(c1->next && Collapse_Chunk(d,c1->next))
- return 1;
-
- if(c1->type == unused && c1->next && c1->next->type == unused) {
- c3 = c1->next;
- c1->size += c3->size;
- c1->end = c3->end;
- c1->next = c3->next;
- c3->next = 0;
- Free_Chunk(c3);
- return 1;
- }
- c3 = c1->part;
- if(!c3)
- return 0;
- if (Collapse_Chunk(d,c1->part))
- return 1;
-
- if (c1->type == whole)
- return 0;
-
- if(c3->type == unused && c3->size == c1->size) {
- Delete_Chunk(d,c1);
- return 1;
- }
- if(c3->type == unused) {
- c2 = new_chunk();
- if (!c2) err(1,"malloc failed");
- *c2 = *c1;
- c1->next = c2;
- c1->disk = d;
- c1->name = strdup("-");
- c1->part = 0;
- c1->type = unused;
- c1->flags = 0;
- c1->subtype = 0;
- c1->size = c3->size;
- c1->end = c3->end;
- c2->offset += c1->size;
- c2->size -= c1->size;
- c2->part = c3->next;
- c3->next = 0;
- Free_Chunk(c3);
- return 1;
- }
- for(c2=c3;c2->next;c2 = c2->next)
- c3 = c2;
- if (c2 && c2->type == unused) {
- c3->next = 0;
- c2->next = c1->next;
- c1->next = c2;
- c1->size -= c2->size;
- c1->end -= c2->size;
- return 1;
- }
-
- return 0;
-}
-#endif