Пример #1
0
int good_strcmp (const char* str1, const char* str2)
{
	int len = strlen (str1);
	if (len != strlen (str2)) return -1;

	return my_memcmp (str1, str2, len);
}
Пример #2
0
bool verify_cleanliness_of_clean_buffer(struct FS_Buffer_Cache * cache,
                                        struct FS_Buffer * buf) {
    struct FS_Buffer dupe_buffer;
    if (buf->flags & FS_BUFFER_DIRTY) {
        return 1;
    } else {
        dupe_buffer.data = Malloc(cache->fsBlockSize);
        if (dupe_buffer.data != NULL) {
            dupe_buffer.fsBlockNum = buf->fsBlockNum;
            /* Read block data into buffer. */
            Do_Buffer_IO(cache, &dupe_buffer, Block_Read);
            if (my_memcmp(buf->data, dupe_buffer.data, cache->fsBlockSize) ==
                0) {
                Free(dupe_buffer.data);
                return 1;
            } else {
                Free(dupe_buffer.data);
                return 0;
            }
            return 1;
        } else {
            /* assume it's good, we're oom. */
            return 1;
        }
    }
}
Пример #3
0
Файл: inf_div.c Проект: k6s/tek1
char		do_div(t_nb *res, t_nb *n1, t_nb *n2, t_base *s_base)
{
  t_nb		*tmp;
  t_nb		*to_free;
  int		cmp;

  if (!(tmp = mk_zero(s_base->base[0])))
    return (-1);
  cmp = 0;
  while (n1->len > tmp->len
	 || (tmp->len == n1->len
	     && (cmp = my_memcmp(tmp->nb, n1->nb, n1->len)) < 0))
    {
      add_one(res, n1->len, s_base->base_len);
      to_free = tmp;
      if (!(tmp = inf_add(tmp, n2, s_base, 0)))
	return (-1);
      free(to_free->nb);
      free(to_free);
    }
  if (n1->len < tmp->len || cmp > 0)
    sub_one(res, n1->len, s_base->base_len);
  free(tmp->nb);
  free(tmp);
  return (0);
}
Пример #4
0
int main() {    

    char arr11[] = {0, '1', '5', '6', '9'};
    char arr12[] = {0, '1', '2', '6', '9'};

    char arr21[] = {0, 1, '\0', 4, 5};
    char arr22[] = {0, 1, 'a', 'b', 'c'};

    char arr31[] = {0, 1, 2, 3, 4};
    char arr32[] = {0, 1, 2, 3, 4};

    printf("arr11[]={\\0,1,5,6,9} \narr12[]={\\0,1,2,6,9} \nmy_memcmp()=%d\n\n", my_memcmp(arr11, arr12, 5));
    printf("arr21[]={\\0,1,\\0,4,5} \narr22[]={\\0,1,a,b,c} \nmy_memcmp()=%d\n\n", my_memcmp(arr21, arr22, 5));
    printf("arr31[]={\\0,1,2,3,4} \narr32[]={\\0,1,2,3,4} \nmy_memcmp()=%d\n\n", my_memcmp(arr31, arr32, 5));


    return 0;
}
Пример #5
0
/*
 查找并返回s2字符串在s1的起始地址
 */
char *my_strstr(const char *s1, const char *s2)
{
    int n = my_strlen(s2);
    
    while (*s1 != '\0') {
        if (!my_memcmp(s1++, s2, n)) {
            return (char *)s1 - 1;
        }
    }
    
    return nullptr;
}
int
main ()
{
  printf ("== Launching sanity test ==\n");

  assert (my_memcpy (NULL, NULL, 0) == NULL);
  assert (my_memcmp (NULL, NULL, 0) == 0);
  assert (my_memset (NULL, 0, 0) == NULL);

  printf ("== Sanity test succeded ==\n");

  return 0;
}
Пример #7
0
/*****************************************************************************************
*   WriteEepromBytes
*   Function : Write data into EEPROM at addr
*   Action   : 
*	Input    : addr--the address which start to Write, buffer--the pointer 
to buffer used to store data
               len-- the length of data needed to read
*	Output   : None
*	Return   : 1--success  0--fail 
*****************************************************************************************/
uint8 WriteEepromBytes(const void *buffer, uint16 addr, uint16 lenth)//(uint16 addr, const void *buffer, uint16 lenth)
{
    uint16 repeat, bleng;
    uint8  cbak[EE_PAGELEN];

    if (lenth == 0)
    {
        return FALSE;
    }

    do
    {    //(addr % EE_PAGELEN) 已经写完的长度
        if(((addr % EE_PAGELEN) + lenth) > EE_PAGELEN) //已经写的长度加上要写数据的长度大于一页的长度
        {
            bleng = EE_PAGELEN - (addr % EE_PAGELEN);
            lenth -= bleng;//下一页需要多少长度
        }
        else //比一页的长度小 则直接赋值
        {
            bleng = lenth;
            lenth  = 0;
        }

        for(repeat = 3; repeat!= 0; repeat--)
        {
            read_IIC_bytes(cbak, EEPROM_DEV, addr, bleng);//(addr, cbak, bleng, EEPROM_DEV)
            if(my_memcmp((uint8*)buffer, cbak, bleng)==0)//比较buffer和cbak在bleng个字节的值
            {
                repeat = 3;     // wirte ok!
                break;          // if the data is same,break
            }
            if(!Write_IIC_Bytes(buffer, EEPROM_DEV, addr, bleng))//(addr, buffer, bleng, EEPROM_DEV))
            {
                return FALSE;
            }
        }

        if(0 == repeat)
        {
            return FALSE;
        }
        buffer  = (uint8 *)buffer + bleng;
        addr += bleng;
    }while(lenth != 0);

    return TRUE;
}
Пример #8
0
int                     cam_gen(t_data *data)
{
  t_cam                 cam;
  t_cam                 old;
  t_bunny_position      origin;

  cam_init_gen(data, &old, &origin);
  while (cam_path_read(data->path, &cam) == 0)
    {
      data->pix = data->big;
      data->obj.cam = cam;
      if (my_memcmp(&cam, &old, sizeof(t_cam)) != 0)
	gen_scene(data);
      old = cam;
      if (jif_add(data->jif, data->pix))
	return (1);
      bunny_blit(&data->win->buffer, &data->pix->clipable, &origin);
      bunny_display(data->win);
    }
  return (0);
}
Пример #9
0
void add_memfilechunk(MemFile *compare, MemFile *current, char *buf, unsigned int size)
{
	static MemFileChunk *compchunk=NULL;
	MemFileChunk *curchunk;
	
	/* this function inits when compare != NULL or when current==NULL */
	if(compare) {
		compchunk= compare->chunks.first;
		return;
	}
	if(current==NULL) {
		compchunk= NULL;
		return;
	}
	
	curchunk= MEM_mallocN(sizeof(MemFileChunk), "MemFileChunk");
	curchunk->size= size;
	curchunk->buf= NULL;
	curchunk->ident= 0;
	BLI_addtail(&current->chunks, curchunk);
	
	/* we compare compchunk with buf */
	if(compchunk) {
		if(compchunk->size == curchunk->size) {
			if( my_memcmp((int *)compchunk->buf, (int *)buf, size/4)==0) {
				curchunk->buf= compchunk->buf;
				curchunk->ident= 1;
			}
		}
		compchunk= compchunk->next;
	}
	
	/* not equal... */
	if(curchunk->buf==NULL) {
		curchunk->buf= MEM_mallocN(size, "Chunk buffer");
		memcpy(curchunk->buf, buf, size);
		current->size += size;
	}
}
Пример #10
0
static void
sigusr1_handler( int signo, siginfo_t *info, void *context )
{
    ssize_t recvlen;
    char mybuf[20];
    unsigned int myprio;
    mqd_t *q = (mqd_t *)info->si_value.sival_ptr;

    CYG_TEST_PASS_FAIL( SIGUSR1 == signo, "correct signal number #1" );
    CYG_TEST_PASS_FAIL( SIGUSR1 == info->si_signo, "correct signal number #2" );
    CYG_TEST_PASS_FAIL( SI_MESGQ == info->si_code, "correct signal code" );

    signals++;

    // retrieve message and compare with buf
    recvlen = mq_receive( *q, mybuf, sizeof(mybuf), &myprio );
    CYG_TEST_PASS_FAIL( recvlen == my_strlen(buf),
                        "receive message length" );
    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, mybuf, my_strlen(buf)),
                        "received message data intact" );
    CYG_TEST_PASS_FAIL( prio == myprio,
                        "received at correct priority" );
}
Пример #11
0
int main(void)
{
#if 0	
	unsigned long a, b;

	printf("input a :");
	scanf("%ld", &a);
	printf("input b :");
	scanf("%ld", &b);

	printf("gcd(%ld,%ld) = %ld\n", a, b, gcd(a, b));
#endif
	char dst[100];
	char *src = "hello world\n";
	char *tmp = dst;
	int i, count;

	printf("input count : ");
	scanf("%d", &count);
	
	for(i = 0; i < sizeof(dst); i++)
		dst[i] = i;

	while(count) {
		if((*tmp = *src) != 0)
			src++;
		tmp++;
		count--;
	}

	for(i = 0; i < sizeof(dst); i++)
		printf((i+1)%16 ? "%.2x " : "%.2x\n", dst[i]);

	printf("\nmemcmp = %d\n", my_memcmp("aahh", "aaa", 3));
	
	return 0;
}
Пример #12
0
int
main(void)
{
    mqd_t q1, q2;
    char buf[20];
    ssize_t recvlen;
    unsigned int prio;
    struct mq_attr attr, oattr;
    mode_t mode;
    int err;

    CYG_TEST_INIT();
    CYG_TEST_INFO( "Starting POSIX message test 1" );

    q1 = mq_open( "/mq1", O_RDWR );
    CYG_TEST_PASS_FAIL( q1 == (mqd_t)-1, "error for non-existent queue" );
    CYG_TEST_PASS_FAIL( ENOENT == errno,
                        "errno correct for non-existent queue" );

    attr.mq_flags = 0;
    attr.mq_maxmsg = 4;
    attr.mq_msgsize = 20;
    mode = S_IRWXU|S_IRWXG|S_IRWXO; // rwx for all

    q1 = mq_open( "/mq1", O_CREAT|O_NONBLOCK|O_WRONLY, mode, &attr );
    CYG_TEST_PASS_FAIL( q1 != (mqd_t)-1, "simple mq_open (write only)" );
    
    err = mq_getattr( q1, &attr );
    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr" );
    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
                        (20 == attr.mq_msgsize) &&
                        (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
                        (O_RDONLY != (attr.mq_flags & O_RDONLY)) &&
                        (O_WRONLY == (attr.mq_flags & O_WRONLY)) &&
                        (O_RDWR != (attr.mq_flags & O_RDWR)) &&
                        (0 == attr.mq_curmsgs ), "getattr attributes correct" );
                        
    err = mq_send( q1, "Vik is brill", sizeof("Vik is brill"), 10 );

    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_send" );
    
    err = mq_getattr( q1, &attr );
    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr after send" );
    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
                        (20 == attr.mq_msgsize) &&
                        (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
                        (O_RDONLY != (attr.mq_flags & O_RDONLY)) &&
                        (O_WRONLY == (attr.mq_flags & O_WRONLY)) &&
                        (O_RDWR != (attr.mq_flags & O_RDWR)) &&
                        (1 == attr.mq_curmsgs ),
                        "getattr attributes correct #2" );
                        
    q2 = mq_open( "/mq1", O_RDONLY|O_CREAT|O_EXCL );
    CYG_TEST_PASS_FAIL( q2 == (mqd_t)-1,
                        "error for exclusive open of existing queue" );
    CYG_TEST_PASS_FAIL( EEXIST == errno,
                        "errno correct for exclusive open of existing queue" );
    
    q2 = mq_open( "/mq1", O_RDONLY );
    CYG_TEST_PASS_FAIL( q2 != (mqd_t)-1, "simple mq_open (read only)" );
    
    err = mq_getattr( q2, &attr );
    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr, different mqd_t" );
    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
                        (20 == attr.mq_msgsize) &&
                        (O_NONBLOCK != (attr.mq_flags & O_NONBLOCK)) &&
                        (O_RDONLY == (attr.mq_flags & O_RDONLY)) &&
                        (O_WRONLY != (attr.mq_flags & O_WRONLY)) &&
                        (O_RDWR != (attr.mq_flags & O_RDWR)) &&
                        (1 == attr.mq_curmsgs ),
                        "getattr attributes correct #3" );

    err = mq_close( q2 );
    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_close" );
    
    q2 = mq_open( "/mq1", O_RDONLY );
    CYG_TEST_PASS_FAIL( q2 != (mqd_t)-1, "mq_open reopen (read only)" );
    
    err = mq_getattr( q2, &attr );
    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr, different mqd_t" );
    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
                        (20 == attr.mq_msgsize) &&
                        (O_NONBLOCK != (attr.mq_flags & O_NONBLOCK)) &&
                        (O_RDONLY == (attr.mq_flags & O_RDONLY)) &&
                        (O_WRONLY != (attr.mq_flags & O_WRONLY)) &&
                        (O_RDWR != (attr.mq_flags & O_RDWR)) &&
                        (1 == attr.mq_curmsgs ),
                        "getattr attributes correct #4" );

    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
    CYG_TEST_PASS_FAIL( recvlen == sizeof("Vik is brill"),
                        "receive message length" );
    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "Vik is brill",
                                        sizeof("Vik is brill")),
                        "received message data intact" );
    CYG_TEST_PASS_FAIL( 10 == prio, "received at correct priority" );

    err = mq_getattr( q1, &attr );
    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr after send" );
    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
                        (20 == attr.mq_msgsize) &&
                        (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
                        (O_RDONLY != (attr.mq_flags & O_RDONLY)) &&
                        (O_WRONLY == (attr.mq_flags & O_WRONLY)) &&
                        (O_RDWR != (attr.mq_flags & O_RDWR)) &&
                        (0 == attr.mq_curmsgs ),
                        "getattr attributes correct #5" );

    attr.mq_flags |= O_NONBLOCK;
    err = mq_setattr( q2, &attr, &oattr );
    CYG_TEST_PASS_FAIL( 0 == err, "mq_setattr O_NONBLOCK" );
    CYG_TEST_PASS_FAIL( (4 == oattr.mq_maxmsg) &&
                        (20 == oattr.mq_msgsize) &&
                        (O_NONBLOCK != (oattr.mq_flags & O_NONBLOCK)) &&
                        (O_RDONLY == (oattr.mq_flags & O_RDONLY)) &&
                        (O_WRONLY != (oattr.mq_flags & O_WRONLY)) &&
                        (O_RDWR != (oattr.mq_flags & O_RDWR)) &&
                        (0 == oattr.mq_curmsgs ),
                        "old attribute correct" );
    err = mq_getattr( q2, &attr );
    CYG_TEST_PASS_FAIL( 0 == err, "mq_getattr after O_NONBLOCK" );
    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
                        (20 == attr.mq_msgsize) &&
                        (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
                        (O_RDONLY == (attr.mq_flags & O_RDONLY)) &&
                        (O_WRONLY != (attr.mq_flags & O_WRONLY)) &&
                        (O_RDWR != (attr.mq_flags & O_RDWR)) &&
                        (0 == attr.mq_curmsgs ),
                        "new attribute correct" );

    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
    CYG_TEST_PASS_FAIL( recvlen == (ssize_t)-1,
                        "mq_receive, empty buffer, non-blocking" );
    CYG_TEST_PASS_FAIL( EAGAIN == errno,
                        "errno correct for non-blocking" );
    
    err = mq_send( q2, "foo", sizeof("foo"), 1 );
    CYG_TEST_PASS_FAIL( -1 == err, "error on mq_send on read-only descriptor" );
    CYG_TEST_PASS_FAIL( EBADF == errno,
                        "errno correct for mq_send on r/o descriptor" );
    
    err = mq_send( q2, "supercalifragilisticexpealidocious", 21, 2 );
    CYG_TEST_PASS_FAIL( -1 == err, "error on mq_send (message too long)" );
    CYG_TEST_PASS_FAIL( EMSGSIZE == errno,
                        "errno correct for mq_send (message too long)" );
    
    err = mq_send( q1, "", sizeof(""), 5 );
    CYG_TEST_PASS_FAIL( 0 == err, "mq_send \"\"" );
    
    err = mq_send( q1, "I love Vik", sizeof("I love Vik"), 7 );
    CYG_TEST_PASS_FAIL( 0 == err, "mq_send (different priority)" );
    
    err = mq_send( q1, "a lot!", sizeof("a lot!"), 7 );
    CYG_TEST_PASS_FAIL( 0 == err, "mq_send (same priority)" );
    
    err = mq_send( q1, "Vik is a babe", sizeof("Vik is a babe"), 6 );
    CYG_TEST_PASS_FAIL( 0 == err, "mq_send (middle priority)" );
    
    err = mq_send( q1, "wibble", sizeof("wibble"), 6 );
    CYG_TEST_PASS_FAIL( -1 == err, "error on mq_send with full queue" );
    CYG_TEST_PASS_FAIL( EAGAIN == errno,
                        "errno correct for mq_send full queue" );
    
    err = mq_getattr( q2, &attr );
    CYG_TEST_PASS_FAIL( 0 == err, "mq_getattr after sends" );
    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
                        (20 == attr.mq_msgsize) &&
                        (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
                        (O_RDONLY == (attr.mq_flags & O_RDONLY)) &&
                        (O_WRONLY != (attr.mq_flags & O_WRONLY)) &&
                        (O_RDWR != (attr.mq_flags & O_RDWR)) &&
                        (4 == attr.mq_curmsgs ),
                        "getattr attributes correct #5" );

    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
    CYG_TEST_PASS_FAIL( recvlen == sizeof("I love Vik"),
                        "receive message length (prioritized) #1" );
    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "I love Vik",
                                        sizeof("I love Vik")),
                        "received message data intact (prioritized) #1" );
    CYG_TEST_PASS_FAIL( 7 == prio,
                        "received at correct priority (prioritized) #1" );

    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
    CYG_TEST_PASS_FAIL( recvlen == sizeof("a lot!"),
                        "receive message length (prioritized) #2" );
    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "a lot!",
                                        sizeof("a lot!")),
                        "received message data intact (prioritized) #2" );
    CYG_TEST_PASS_FAIL( 7 == prio,
                        "received at correct priority (prioritized) #2" );

    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
    CYG_TEST_PASS_FAIL( recvlen == sizeof("Vik is a babe"),
                        "receive message length (prioritized) #3" );
    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "Vik is a babe",
                                        sizeof("Vik is a babe")),
                        "received message data intact (prioritized) #3" );
    CYG_TEST_PASS_FAIL( 6 == prio,
                        "received at correct priority (prioritized) #3" );

    recvlen = mq_receive( q2, buf, 0, &prio );
    CYG_TEST_PASS_FAIL( recvlen == (ssize_t)-1,
                        "mq_receive, zero-sized buffer" );

    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
    CYG_TEST_PASS_FAIL( recvlen == sizeof(""),
                        "receive message length (prioritized) #4" );
    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "",
                                        sizeof("")),
                        "received message data intact (prioritized) #4" );
    CYG_TEST_PASS_FAIL( 5 == prio,
                        "received at correct priority (prioritzed) #4" );

    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
    CYG_TEST_PASS_FAIL( recvlen == (ssize_t)-1,
                        "mq_receive, empty buffer, non-blocking #2" );
    CYG_TEST_PASS_FAIL( EAGAIN == errno,
                        "errno correct for non-blocking #2" );
    
    err = mq_send( q1, "12345678901234567890", 20, 15 );
    CYG_TEST_PASS_FAIL( 0 == err, "mq_send (before closing)" );
    
    err = mq_unlink( "/foo" );
    CYG_TEST_PASS_FAIL( -1 == err, "mq_unlink (wrong name)" );
    CYG_TEST_PASS_FAIL( ENOENT == errno,
                        "errno correct for mq_unlink (wrong name)" );

    err = mq_unlink( "/mq1" );
    CYG_TEST_PASS_FAIL( 0 == err, "mq_unlink (before closing)" );

    err = mq_close( q1 );
    CYG_TEST_PASS_FAIL( 0 == err, "mq_close (send descriptor)" );

    recvlen = mq_receive( q2, buf, sizeof(buf), &prio );
    CYG_TEST_PASS_FAIL( recvlen == 20,
                        "receive message length (mid close)" );
    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, "12345678901234567890", 20 ),
                        "received message data intact (mid close)" );
    CYG_TEST_PASS_FAIL( 15 == prio,
                        "received at correct priority (mid close)" );

    err = mq_close( q2 );
    CYG_TEST_PASS_FAIL( 0 == err, "mq_close (receive descriptor)" );

    q1 = mq_open( "/mq1", O_RDONLY );
    CYG_TEST_PASS_FAIL( q1 == (mqd_t)-1, "error for non-existent queue" );
    CYG_TEST_PASS_FAIL( ENOENT == errno,
                        "errno correct for non-existent queue" );

    CYG_TEST_EXIT("POSIX message test 1");

    return 0;
} // main()
Пример #13
0
/*************************************************************************
 * GET THE NEXT DIRECTORY ENTRY FROM A DIRECTORY BLOCK
 *
 * - This procedure uses static local variables
 * - These variables are initialized by setting "first_time" to TRUE
 * - Entries, which are zeroed, are skipped.
 * - If we get a new block-number which was previously used as an active
 *   directory-block and is referred more than one time in the reference
 *   bit-map, we skip it.
 * - All blocks used are marked as being used
 *
 * Parameters : parent     = Pointer to the parent directory entry
 *		first_time = Init flag
 *		block      = pointer to var to hold the actual block number
 *		off	   = pointer to var to hold the actual offset (index)
 * Return     : A pointer to the entry or NULL, if no more valid blocks
 *		are available. This signals the end of the inspection
 *
 *************************************************************************/
struct dir_elem *
get_next_entry ( struct inode *parent, word first_time, daddr_t *block, word *off )
{
 static word index;
 static struct buf *bp;
 static word bnr, empty;
					/* get_next_entry is called the */
 if ( first_time )			/* first time			*/
 {
#if DEBUG
IOdebug ("	get_next_entry :	First time initialization.");
#endif
	index  = 0;			/* Initialization of index	*/
	empty  = 0;			/* No empty entry at first	*/
 }

#if DEBUG
IOdebug ("	get_next_entry :	Get a new entry.");
#endif
					/* An unknown number of blocks	*/
 for ( ;; )				/* referred by the dir-blks 	*/
 {					/* Scan all directory entries	*/
	for ( ; index < i_fs.fs_maxdpb ; index++ )
 	{
		if ( index == 0 )	/* Beginning of a new block ?	*/
		{			/* After first try, we have to	*/
					/* release previously used blks */
			if ( ! first_time )
			{
				if ( changes_de )
				{
#if DEBUG
IOdebug ("	get_next_entry :	Update modified directory-block on disk.");
#endif
					test_bwrite ( bp );
				}
				else
				{
#if DEBUG
IOdebug ("	get_next_entry :	Release non modified directory-block");
#endif
					brelse ( bp->b_tbp, TAIL );
				}
			}
					/* Loop until we get an "unused"*/
					/* and single referred block-num*/
			for ( ;; )
			{
					/* Get a "new" blocknumber	*/ 
				bnr = get_next_bnr ( parent, first_time, FALSE );
					/* We have reached the last blk	*/
				if ( bnr == 0 )	
					/* The last entry in this di -	*/
					/* rectory was reached:		*/
					
					return (struct dir_elem *) NULL;
					
					/* Multiple use of this block ?	*/
				if ( bitmap_get_used (bnr) &&
				     bitmap_get (bnr) > 1 )
				{
#if DEBUG
IOdebug ("	get_next_entry :	Skip over multiple referred dir-block.");
#endif
					first_time = FALSE;
					continue;
				}
				else
					/* We have a usable block-num	*/
					break;
			}
					/* Mark the block as being used	*/
			bitmap_set_used (bnr);					
					/* Read the block into memory	*/
			bp = bread ( 0, bnr, 1, SAVEA );

			changes_de = 0;	/* Nothing changed so far...	*/
		}
				/* Wiped out content ? ( A mode-field	*/
				/* set to FREE is ignored, because it	*/
				/* could be an error. )			*/
		if ( ! my_memcmp ( (void *) &dir_cmp, (void *) &bp->b_un.b_dir[index], 
	    			 sizeof (struct dir_elem) ) )
	    	{
	    		empty++;	/* Another empty slot found	*/
			continue;	/* Get the next entry		*/
		}
	
		*block = bnr;		/* Save block-number and index	*/
		*off   = index;
		index++;		/* Next entry			*/
					/* Return the new entry		*/
		return &bp->b_un.b_dir[*off];
		
 	} /* end of <for (index)> */
					/* After examination of a whole	*/
					/* block we check whether we	*/
					/* have found any non-zeroed	*/
					/* directory entry.		*/
	if ( empty == i_fs.fs_maxdpb )
	{
#if DEBUG
IOdebug ("	get_next_entry :	Block %d is totally empty",
	 bnr );
#endif
		first_time = FALSE;	/* To prevent get_next_bnr()	*/
					/* from another initialization	*/
	}
	empty = 0;			/* We have no empty entries at	*/
					/* first again.			*/
 	index = 0;			/* Start-position in a new	*/
 					/* directory block		*/
 } /* end of <for (;;)> */
 
}
Пример #14
0
int
main(void)
{
    mqd_t q1;
    struct mq_attr attr;
    mode_t mode;
    int err;
    ssize_t recvlen;
    char mybuf[20];
    unsigned int myprio;
    struct sigevent ev;
    struct sigaction act;

    CYG_TEST_INIT();
    CYG_TEST_INFO( "Starting POSIX message test 2" );

#if 0
    if ( 0 != pthread_create( &thr, NULL, &thread, NULL ) ) {
        CYG_TEST_FAIL_FINISH( "Couldn't create a helper thread" );
    }
#endif

    attr.mq_flags = 0;
    attr.mq_maxmsg = 4;
    attr.mq_msgsize = 20;
    mode = S_IRWXU|S_IRWXG|S_IRWXO; // rwx for all

    q1 = mq_open( "/mq1", O_CREAT|O_NONBLOCK|O_RDWR, mode, &attr );
    CYG_TEST_PASS_FAIL( q1 != (mqd_t)-1, "simple mq_open (write only)" );
    
    err = mq_getattr( q1, &attr );
    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_getattr" );
    CYG_TEST_PASS_FAIL( (4 == attr.mq_maxmsg) &&
                        (20 == attr.mq_msgsize) &&
                        (O_NONBLOCK == (attr.mq_flags & O_NONBLOCK)) &&
                        (O_RDWR == (attr.mq_flags & O_RDWR)) &&
                        (0 == attr.mq_curmsgs ), "getattr attributes correct" );


    act.sa_sigaction = &sigusr1_handler;
    sigfillset( &act.sa_mask ); // enable all signals
    act.sa_flags = SA_SIGINFO;
    
    if ( 0 != sigaction( SIGUSR1, &act, NULL ) ) {
        CYG_TEST_FAIL_FINISH( "Couldn't register signal handler" );
    }

    ev.sigev_notify = SIGEV_SIGNAL;
    ev.sigev_signo = SIGUSR1;
    ev.sigev_value.sival_ptr = (void *)&q1;

    err = mq_notify( q1, &ev );
    CYG_TEST_PASS_FAIL( 0 == err, "simple mq_notify" );

    my_strcpy( buf, "Vik is the best" );
    prio = 7;
    err = mq_send( q1, buf, my_strlen(buf), prio );

    CYG_TEST_PASS_FAIL( 0 == err, "mq_send #1" );

    CYG_TEST_PASS_FAIL( 1 == signals, "got notification" );

    my_strcpy( buf, "Scrummy Vik" );
    prio = 6;
    err = mq_send( q1, buf, my_strlen(buf), prio );
    CYG_TEST_PASS_FAIL( 0 == err, "mq_send #2" );

    CYG_TEST_PASS_FAIL( 1 == signals, "correctly didn't get notification" );

    recvlen = mq_receive( q1, mybuf, sizeof(mybuf), &myprio );
    CYG_TEST_PASS_FAIL( recvlen == my_strlen(buf),
                        "receive message length" );
    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, mybuf, my_strlen(buf)),
                        "received message data intact" );
    CYG_TEST_PASS_FAIL( prio == myprio,
                        "received at correct priority" );

    err = mq_notify( q1, &ev );
    CYG_TEST_PASS_FAIL( 0 == err, "mq_notify #2" );

    err = mq_notify( q1, &ev );
    CYG_TEST_PASS_FAIL( -1 == err, "second mq_notify returns error" );
    CYG_TEST_PASS_FAIL( EBUSY == errno,
                        "errno correct for second mq_notify error" );

    err = mq_notify( q1, NULL );
    CYG_TEST_PASS_FAIL( 0 == err, "clear notification" );

    my_strcpy( buf, "Vik is k3wl" );
    prio = 8;
    err = mq_send( q1, buf, my_strlen(buf), prio );

    CYG_TEST_PASS_FAIL( 0 == err, "mq_send #2" );

    CYG_TEST_PASS_FAIL( 1 == signals, "correctly didn't get notification #2" );

    recvlen = mq_receive( q1, mybuf, sizeof(mybuf), &myprio );
    CYG_TEST_PASS_FAIL( recvlen == my_strlen(buf),
                        "receive message length" );
    CYG_TEST_PASS_FAIL( 0 == my_memcmp( buf, mybuf, my_strlen(buf)),
                        "received message data intact" );
    CYG_TEST_PASS_FAIL( prio == myprio,
                        "received at correct priority" );
    
    err = mq_close( q1 );
    CYG_TEST_PASS_FAIL( 0 == err, "mq_close" );

    err = mq_unlink( "/mq1" );
    CYG_TEST_PASS_FAIL( 0 == err, "mq_unlink" );

    CYG_TEST_EXIT("POSIX message test 2");

    return 0;
} // main()
Пример #15
0
/************************************************************************
 * BASIC TEST ROUTINES TO CHECK UNIQUE DATA STRUCTURES LIKE SUPERBLOCK AND
 * ROOT DIRECTORY AND GET MEMORY FOR THE CHECKER
 *
 * - Make sure, that the superblock and all copies are valid.
 *
 *   THIS TEST HAS BEEN REMOVED FROM THE BASIC VERSION, BECAUSE THE SUPERBLOCK
 *   DATA IS ACTUALLY NOT USED BY THE FILE-SERVER. ALL DATA, DESCRIBING A FILE
 *   SYSTEM IS DERIVED FROM 'devinfo'. ON THE OTHER SIDE, IT IS A NON-TRIVIAL
 *   TASK TO FIND OTHER, EVENTUALLY PARTLY DAMAGED SUPERBLOCKS ON THE MEDIA TO
 *   BE CHECKED. TO HAVE A BASIC IDEA, WHETHER THE RELEVANT DATA (number of
 *   cyl.groups, cyl.group size and cyl.group offset) KEPT IN THE 'devinfo'-
 *   FILE AND ON DISK DESCRIBE THE SAME PHYSICAL DISK, THEY ARE COMPARED FOR
 *   ALL CYLINDER-GROUPS.
 *  
 * - Compare the # number of free blocks in the bit-maps with the
 *   values, referenced in the cylinder group info structs.
 * - Allocate all needed memory for the checker.
 * - Check the root-directory inode and look for the /lost+found - directory
 *
 * Parameter  : - nothing -
 * Return     : TRUE  = no error at all
 *		FALSE = occurrence of a fatal error
 *
 *************************************************************************/
word
check_unique ( void )
{
 struct fs tmp;			/* For intermediate operation		*/
 struct buf *bp, *bp_2;
 word cgnr, i, j, c, free_cnt, ecnt, try, off;

 /*--------- Make a basic comparison of file-system parameters ---------*/

 IOdebug ("%s***    Step 1.1 : Plausibility test of file-system parameters", S_INFO);
 
					/* cgnr and ncg are the values	*/
					/* taken from devinfo. If no	*/
					/* valid superblock is found 	*/
					/* there or the disk parameters	*/
					/* are different, the checking	*/
					/* process is aborted.		*/
					
					/* Make incore copies of the 	*/
					/* superblock data into i_fs and*/
					/* incore_fs.			*/
 /*------------------ Tests on the super-block -------------------------*/

				/* We have to copy the first 		*/
				/* superblock from the cg 0 info-block. */
 bp = bread ( 0, 2, 1, SAVEA );

 memcpy ( &tmp, &bp->b_un.b_info->fs, sizeof (struct fs) );
 brelse ( bp->b_tbp, TAIL );

 				/* Run until we have a valid copy and	*/
 				/* scan the cylinder groups		*/
 for ( cgnr = 0 , try = -1 ;; cgnr++ ) 
 {	
	corrupt_cnt = 0;	/* At the beginning: no errors at all	*/
	try++;			/* Count the tries which are needed to	*/
				/* get a valid super-block.		*/
#if DEBUG
IOdebug ("	check_unique :	Try to validate a sample superblock.");
#endif
				/*------- I.Definitely errors ----------*/
				/* Block-no 1-3 are always the same !	*/
	if ( tmp.fs_sblknr != 1 || tmp.fs_iblknr != 2 || tmp.fs_rblknr != 3 )
		corrupt_cnt++;
				/* The magic number is fixed.		*/
	if ( tmp.fs_magic != MAGIC_NUMBER )
		corrupt_cnt++;

	if ( tmp.fs_szfs != sizeof (struct fs) )
		corrupt_cnt++;
			
	if ( tmp.fs_szcg != sizeof (struct cg) )
		corrupt_cnt++;
				/*------ II.Plausibility errors	--------*/
	if ( tmp.fs_size != tmp.fs_cgsize * tmp.fs_ncg )
		corrupt_cnt++;
	if ( tmp.fs_dsize != tmp.fs_size - tmp.fs_ncg - 3 )
		corrupt_cnt++;
	if ( tmp.fs_fsize != tmp.fs_bsize / tmp.fs_frag )
		corrupt_cnt++;
	if ( tmp.fs_maxdpb != tmp.fs_bsize / sizeof (struct dir_elem) )
		corrupt_cnt++;
	if ( tmp.fs_maxcontig != tmp.fs_bsize / sizeof (daddr_t) )
		corrupt_cnt++;
	if ( tmp.fs_ncgcgoff != tmp.fs_ncg * tmp.fs_cgoffset )
		corrupt_cnt++;
	if ( tmp.fs_minfree < 0 || tmp.fs_minfree > 99 )
		corrupt_cnt++;		
	if ( tmp.fs_psmal > tmp.fs_maxpsz || tmp.fs_pmedi > tmp.fs_maxpsz ||
	     tmp.fs_phuge > tmp.fs_maxpsz )
		corrupt_cnt++;

					/* Were there errors detected ?	 */
	if ( corrupt_cnt )
	{
		unique_err++;
		if ( cgnr == 0 )
			cgnr++;
			
		IOdebug ("The Superblock is damaged (%d errors counted) !",
			    corrupt_cnt);
					/* Is it possible to select 	 */
					/* automatically a new one ?	 */
		if ( tmp.fs_size     == tmp.fs_cgsize * tmp.fs_ncg &&
		     tmp.fs_ncgcgoff == tmp.fs_cgoffset * tmp.fs_ncg &&
		     tmp.fs_size     != 0 &&
		     tmp.fs_ncgcgoff != 0 )
		{
			IOdebug ("Try to interpret block no: %d as an info-block.",
	 			    map_cgtoib (cgnr,tmp.fs_cgoffset,tmp.fs_cgsize));
	 			    
					/* Read in info-blk from next cg */
			bp = bread ( 0, map_cgtoib (cgnr,tmp.fs_cgoffset,tmp.fs_cgsize),
				     1, SAVEA );
				     
			/* There are possibly two reasons why we cannot */
			/* read the block. If we have used a block-num  */
			/* which is invalid, we need help from the user */
			/* to find a correct number for an info-block	*/

				     	/* Copy in temporary struct	*/
			memcpy ( &tmp, &bp->b_un.b_info->fs,
				 sizeof (struct fs) );
				 	/* Release unused packet	*/
			brelse ( bp->b_tbp, TAIL );
					/* Try to validate the new copy	*/
					/* of the Superblock.		*/
			continue;
		}
		else			/* No automatically selection:	*/
					/* Give the user the choice to	*/
		{			/* select manually a new one	*/
			IOdebug ("Unable to select a new info block automatically!");
					/* Assisted search or manual	*/
					/* 'rebuild' of a superblock!	*/
				return FALSE;
		}
	}
	else				/* No errors were detected	*/
	{
		if ( try > 0 )
			IOdebug ("Valid superblock in use now !");
					/* Keep the valid data incore 	*/
					/* in a separated storage area.	*/
		memcpy ( &incore_fs, &tmp, sizeof (struct fs) );
 					/* Make a copy in i_fs, which is*/
					/* for exclusive checker's use	*/
		memcpy ( &i_fs, &tmp, sizeof (struct fs) );
		break;		 	/* We can finish the search for */
					/* a valid superblock !		*/
	} /* end of <if (corrupt_cnt)> */

 } /* end of <for(cgnr)> */

			/* At this point we are sure, that the incore-	*/
			/* copy of the super-block is valid. So we can	*/
			/* use it further on, if we need file system	*/
			/* parameters!					*/
		
 { 	
 					/* Update each cylinder-group	*/
					/* if necessary.		*/
	for ( cgnr = 0 ; cgnr < i_fs.fs_ncg ; cgnr++ )
 	{				/* Read appropriate info block	*/
		bp = bread ( 0, map_cgtoib (cgnr,i_fs.fs_cgoffset,i_fs.fs_cgsize),
			     1, SAVEA );
	
#if DEBUG
IOdebug ("	check_unique :	Compare it with the copy in cylinder-group %d.", cgnr);
#endif
					/* Updating is only recommended, */
					/* if changes were made.	 */
		if ( my_memcmp ( &i_fs, &bp->b_un.b_info->fs, tmp.fs_szfs ) )
		{
#if DEBUG
IOdebug ("	check_unique :	Copy superblock to cylinder-group %d.", cgnr);
#endif
			unique_err++;
					/* Update it's superblock copy	 */
			memcpy ( &bp->b_un.b_info->fs, &i_fs, sizeof (struct fs) );
					/* ... and write it back to disk */
			fst.corrected_sb++;
			test_bwrite ( bp );
		}				
		else			/* They are the same: don't copy */
			brelse ( bp->b_tbp, TAIL );
	} /* end <for (cgnr)> */
 }
				/* Report differences between data kept  */
				/* in the superblock and in the 'devinfo'*/
				/* structures 				 */
#if DEBUG
IOdebug ("	check_unique : Compare 'devinfo' data with the superblock");
#endif

 if ( i_fs.fs_ncg != vvi->CgCount )
 	IOdebug ("Number of cylinder groups               Sb : %4d / devinfo : %d", 
 	            i_fs.fs_ncg, vvi->CgCount);
 if ( i_fs.fs_cgsize != vvi->CgSize )
 	IOdebug ("Size of a cylinder group                Sb : %4d / devinfo : %d", 
 	            i_fs.fs_cgsize, vvi->CgSize);
 if ( i_fs.fs_cgoffset != vvi->CgOffset )
 	IOdebug ("Relative offset into a cylinder group   Sb : %4d / devinfo : %d", 
 		    i_fs.fs_cgoffset, vvi->CgOffset);
 if ( i_fs.fs_psmal != fsi->SmallPkt )
 	IOdebug ("Size of a of small packet               Sb : %d / devinfo : %d", 
 		    i_fs.fs_psmal, fsi->SmallPkt);
 if ( i_fs.fs_pmedi != fsi->MediumPkt )
 	IOdebug ("Size of a of medium packet              Sb : %d / devinfo : %d", 
 	  	    i_fs.fs_pmedi, fsi->MediumPkt);
 if ( i_fs.fs_phuge != fsi->HugePkt )
 	IOdebug ("Size of a huge packet                   Sb : %d / devinfo : %d", 
 		    i_fs.fs_phuge, fsi->HugePkt);
 if ( i_fs.fs_pscnt != fsi->SmallCount )
 	IOdebug ("Number of samll packets                 Sb : %d / devinfo : %d", 
 		    i_fs.fs_pscnt, fsi->SmallCount);
 if ( i_fs.fs_pmcnt != fsi->MediumCount )
 	IOdebug ("Number of medium packtes                Sb : %d / devinfo : %d", 
 	            i_fs.fs_pmcnt, fsi->MediumCount);
 if ( i_fs.fs_phcnt != fsi->HugeCount )
 	IOdebug ("Number of huge packets                  Sb : %d / devinfo : %d", 
 	            i_fs.fs_phcnt, fsi->HugeCount);
 if ( i_fs.fs_maxnii != fsi->MaxInodes )
 	IOdebug ("Maximal number of incore inodes         Sb : %d / devinfo : %d", 
 	            i_fs.fs_maxnii, fsi->MaxInodes);
 if ( i_fs.fs_minfree != vvi->MinFree )
 	IOdebug ("Percentage of space to be kept free     Sb : %d / devinfo : %d", 
 	            i_fs.fs_minfree, vvi->MinFree);

					
 /*---- To ease addressing of info-blocks: create an info-bnr table ----*/
 
#if DEBUG
IOdebug ("	check_unique :	Create an info-block number table.");
#endif
 					/* Calculate all block numbers	*/
 for ( cgnr = 0 ; cgnr < i_fs.fs_ncg ; cgnr++ )
 					/* ... and fill the table	*/
 	info_blocks[cgnr] = map_cgtoib (cgnr, i_fs.fs_cgoffset, i_fs.fs_cgsize);

 
 /*--------- Discrepancy between bit-maps and cg-info ?	----------------*/

			/* This part is only used to detect differences	*/
			/* in the bit-maps and summary-structures and   */
			/* to report them. No attempts to correct them	*/
			/* are made. This is done later by check_blocks.*/ 
			
 IOdebug ("%s***    Step 1.2 : First inspection of bitmap-data", S_INFO);

					/* Scan all cylinder groups	*/
 for ( corrupt_cnt = 0 , cgnr = 0 ; cgnr < i_fs.fs_ncg ; cgnr++ )
 {					/* Read the cg info-block	*/
	bp = bread ( 0, info_blocks[cgnr], 1, SAVEA );
					/* Read error			*/
	if ( bp == (struct buf *) NULL )
	{
		IOdebug ("%sUnexpected read error for block no: %d.",
			    S_SERIOUS, info_blocks[cgnr]);
		return FALSE;
	}
	
	if ( bp->b_un.b_info->cgx.cg_cgx != cgnr ) {
		IOdebug ("%sInvalid cgnr (%d) found in info block %d!", S_WARNING, bp->b_un.b_info->cgx.cg_cgx ,cgnr);	
	}
					/* Scan through the bit-map !	*/
	for ( i = 0 , free_cnt = 0 , ecnt = 0 ; i < i_fs.fs_cgsize ; i++ )
	{
		switch ( bp->b_un.b_info->cgx.cg_free[i] )
		{			/* Test for errors		*/
			case 0x00 : free_cnt++;  
 				    break;
			case 0xff : continue;
				    break;
			default   : ecnt++;
				    fst.bitmap_errors++;
				    corrupt_cnt++;
		}
	}
	
	if ( free_cnt != bp->b_un.b_info->cgx.cg_s.s_nbfree )
	{				/* By comparing with cg-sum	*/
		corrupt_cnt++;
		unique_err++;
		fst.summary_errors++;
	IOdebug ("%sDifferent number of free blocks found.", S_WARNING);
	IOdebug ("%s> Cyl. Group : %d   FREE  counted= %d   cg-summary= %u",
		            S_INFO, cgnr, free_cnt,
			    bp->b_un.b_info->cgx.cg_s.s_nbfree);
	}

					/* Definitely errors in maps ?	*/
	if ( ecnt )			/* ( != 0 && != 0xff )		*/
	{
		unique_err++;
		IOdebug ("%sCorrupted bits in bit-map found.", S_WARNING);
		IOdebug ("%s> Cyl. Group : %d   ERRORS       =%d  blocks",
			    S_INFO, cgnr, ecnt);
					/* We have reached the limit ?	*/
		if ( ecnt > i_fs.fs_cgsize * maxbmerr / 100 )
		{			/* Note cg-bitmap as unusable	*/
			cg_bitmap_usable[cgnr] = FALSE;
			IOdebug ("%sThe bit-map is not usable!", S_SERIOUS);
		}
		else
			cg_bitmap_usable[cgnr] = TRUE;
 			
	}				/* We have found a bitmap in an	*/
	else				/* usable state !		*/
		cg_bitmap_usable[cgnr] = TRUE;
		
					/* Release unused block		*/
	brelse ( bp->b_tbp, TAIL );
 } /* end < for (cgnr) > */
 
 /*--------- Allocate enough memory for a reference bit-map array ------*/

 IOdebug ("%s***    Step 1.3 : Allocate memory for reference bit-map array.", S_INFO);

 bit_maps_allocated = alloc_ref_maps ();			

 if ( ! bit_maps_allocated )	/* No success again, that's bad!  */
 {
	IOdebug ("%sUnable to allocate memory for reference bit-maps.", S_FATAL);
	return FALSE;
 }
 					/* Blocks 0-2 always allocated !  */
 bit_maps[0][0] = 1;			/* Boot-block			  */
 found_blocks++;
 bitmap_incr (1);			/* Summary block		  */
 found_blocks++;
					/* Mark all info-blocks as being  */
					/* allocated.			  */
 for ( cgnr = 0 ; cgnr < i_fs.fs_ncg ; cgnr++ )
 {
 	found_blocks++;
	bitmap_incr (info_blocks[cgnr]); 
 }

 /*-----------  Prepare the hash-table for directory entries  ------------*/

#if DEBUG
IOdebug ("	check_unique :	Prepare directory-entry hash table.");
#endif

					/* We have to initialize all	*/
 for ( i = 0 ; i < DEHASHSZ ; i++ )	/* hash-pointers !		*/
	de_hash_tab[i].denxt = (struct de_name *) NULL;
 
 /*------  Prepare the hash-table for duplicate block numbers  ---------*/

#if DEBUG
IOdebug ("	check_unique :	Prepare duplicate block-number hash table.");
#endif

					/* We have to initialize all	*/
 for ( i = 0 ; i < DUPHASHSZ ; i++ )	/* hash-pointers !		*/
	dup_hash_tab[i].dupnxt = (struct dup_bnr *) NULL;

 /*--------  Prepare the hash-table for symbolic link references  ------*/ 
 
#if DEBUG
IOdebug ("	check_unique :	Prepare symbolic-link hash-table.");
#endif
					/* We have to initialize all	*/
 for ( i = 0 ; i < LINKHASHSZ ; i++ )	/* hash-pointers		*/
 	link_hash_tab[i].lnnxt = (struct de_link *) NULL;
 
 /*--------------- Valid root directory data ? -------------------------*/

 IOdebug ("%s***    Step 1.4 : Check the root directory inode.", S_INFO);

					/* Read summary block with the	*/
 bp = bread ( 0, 1, 1, SAVEA );		/* root-dir inode in it.	*/
					/* if read fails, longjmp 	*/
					/* term_jmp			*/
 changes_de = 0;			/* Nothing done so far ...	*/
 					/* Check the root-dir entry 	*/
 if ( ! validate_entry ( &bp->b_un.b_sum->root_dir , "/", Type_Directory, TRUE ) )
 {					/* Is it totally damaged !	*/
 
 		/* It is a very dangerous situation, if we have no root-*/
 		/* directory available. The user can create an		*/
 		/* empty one and hope, that lost subdiretory-information*/
 		/* is picked up during the "lost+found" pass over the	*/
 		/* cylinder-group bit-maps.				*/

	unique_err++;
	IOdebug ("%sThe root-directory is not usable !", S_SERIOUS);
					/* Pioneer's work: we create a	*/
					/* new inode from scratch !	*/
	IOdebug ("%sA new root-directory is created from scratch.", S_INFO);
	
 					/* Pioneer's work: we create a	*/
 					/* new root-inode from scratch  */
 	create_new_root_dir ( &bp->b_un.b_sum->root_dir );
 					/* Write the root-inode back on */
 					/* disk.			*/
 	test_bwrite ( bp );
 }
 else					/* After finding a usable root- */
 {					/* directory entry ...		*/
	if (!bp->b_un.b_sum->sum_same)
		unique_err++;
 	if ( changes_de )		/* Any changes made ?		*/
 	{
#if DEBUG
IOdebug ("	check_unique :	Update root-directory inode on disk.");
#endif
		unique_err++;
					/* Write corrected summary-block */
 		test_bwrite ( bp );	/* directly to disk		 */
 	}
 	else
		brelse ( bp->b_tbp, TAIL );
 }

 /*----------------  Look for the "lost+found" directory  --------------*/


 IOdebug ("%s***    Step 1.5 : Look for the '/lost+found'- directory.", S_INFO);

 bp = bread ( 0, 1, 1, SAVEA );		/* Get root-directory		*/
					/* if read fails, longjmp 	*/
					/* term_jmp			*/
					
 					/* Look for the "lost+found"-dir */
 bp_2 = search_entry ( &bp->b_un.b_sum->root_dir.de_inode, "lost+found", &off );
					/* We have found it ?		*/
 if ( bp_2 != (struct buf *) NULL )
 {					/* We have found a usable 	*/
	lost_found = TRUE;		/* /lost+found - directory.	*/
	brelse ( bp_2->b_tbp, TAIL );
	brelse ( bp->b_tbp, TAIL );
 }
 					/* If we have not found the 	*/
 else					/* /lost+found-inode, we have to */
 {					/* create a new one.		*/
 	IOdebug ("%sUnable to find a '/lost+found' entry in the root-directory.", S_WARNING);
	IOdebug ("%sA new '/lost+found' entry is created.", S_INFO);
	unique_err++;
 	if ( create_lostfound_inode ( &bp->b_un.b_sum->root_dir.de_inode ) )
	{
		IOdebug ("%sHave created a new /lost+found directory!", S_INFO);
		lost_found = TRUE; 	
 		test_bwrite ( bp );	/* Write modified root back.	*/
 	}
 	else				/* We cannot create a /lost+found*/
 	{				/* inode, because we have no    */
 					/* slot available.		*/
		IOdebug ("%sCannot create a new '/lost+found' directory !", S_WARNING);
		lost_found = FALSE;
		brelse ( bp->b_tbp, TAIL );
	}
 }

 return TRUE;
}

/*--  Procedures dealing with the creation of a new basic structures ---*/

/************************************************************************
 * CREATE A TOTALLY EMPTY ROOT-DIRECTORY ENTRY FROM SCRATCH
 *
 * - This procedure is called, if the checker was not able to find a 
 *   valid root-directory.
 *
 * Parameter   : dp    = Pointer to the root directory-element
 * Return      : - nothing -
 *
 ***********************************************************************/
static void
create_new_root_dir ( struct dir_elem *dp )
{
 Date date;
 
#if DEBUG
IOdebug ("	create_new_root_dir :	Create the new entry");
#endif
					/* Clear the directory-entry	*/
 memset ( dp, 0, sizeof (struct dir_elem) );
 					/* .. and fill in with the data	*/
 					/* for the root-directory	*/
 strcpy ( dp->de_name, i_fs.fs_name );
 dp->de_inode.i_mode   = Type_Directory;
 dp->de_inode.i_matrix = DefDirMatrix;
 date = GetDate ();
 dp->de_inode.i_ctime  = date;
 dp->de_inode.i_mtime  = date;
 dp->de_inode.i_atime  = date;
}