⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 namei.c

📁 阿基米德操作系统的源代码
💻 C
字号:

/////////////////////////////////////////////////////////////////////
#include "general.h"
#include "s_isdirreg.h"

#include "hd_info_struct.h"
#include "dir_entry.h"
#include "msdos_dir_entry.h"
#include "d_inode.h"
#include "m_inode.h"
#include "buffer_head.h"
#include "fat_cache.h"
#include "file.h"
#include "hd_request_struct.h"
#include "super_block.h"

#include "common_head.h"
/////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
int match(int len,const char * name,struct dir_entry * de){	int same;	if ((!de) || (!de->inode) || (len == 0) || (len > NAME_LEN))		return 0;	if (len < NAME_LEN && de->name[len])		return 0;	__asm__("cld\n\t"			"gs ; repe ; cmpsb\n\t"			"setz %%al"		   :"=a" (same)		   :"0" (0),"S" ((long) name),"D" ((long) de->name),"c" (len));	return same;}struct buffer_head * find_entry(struct m_inode * dir,	const char * name, int namelen, struct dir_entry ** res_dir){	struct buffer_head * bh;	struct dir_entry   * de;
	int    entries,i,block,new_block_flag;	
	*res_dir = NULL;

	if ((namelen == 0) || (namelen > NAME_LEN))		return NULL;
	if (!(block = dir->i_zone[0]))		return NULL;	if (!(bh = bread(dir->i_dev,block,0)))		return NULL;
	de = (struct dir_entry *) bh->b_data;

	new_block_flag = 0;
	entries = dir->i_size / (sizeof (struct dir_entry));
	i = 0;	while (i < entries) {		if ((new_block_flag) || ((char *)de >= (char *)(bh->b_data + BLOCK_SIZE))) {			brelse(bh);			bh = NULL;			if (!(block = bmap(dir , i / DIR_ENTRIES_PER_BLOCK))){
				i += DIR_ENTRIES_PER_BLOCK;
				new_block_flag = 1;
				continue;				
			}
			if (!(bh = bread(dir->i_dev,block,0)))
				return NULL;
			de = (struct dir_entry *) bh->b_data;
			new_block_flag = 0;		}		if (match(namelen,name,de)) {			*res_dir = de;			return bh;		}		de++;		i++;	}	brelse(bh);	return NULL;}struct buffer_head * add_entry(struct m_inode * dir,	const char * name, int namelen, struct dir_entry ** res_dir){	struct buffer_head * bh;	struct dir_entry   * de;	int    i,block;
	*res_dir = NULL;	if ((namelen == 0) || (namelen > NAME_LEN))		return NULL;	if (!(block = dir->i_zone[0]))		return NULL;	if (!(bh = bread(dir->i_dev,block,0)))		return NULL;
	de = (struct dir_entry *) bh->b_data;

	i = 0;	while (1) {		if ((char *)de >= (char *)(bh->b_data + BLOCK_SIZE)) {			brelse(bh);			bh = NULL;			block = create_block(dir,i / DIR_ENTRIES_PER_BLOCK);			if (!block)				return NULL;
			if (!(bh = bread(dir->i_dev,block,0)))
				return NULL;			de = (struct dir_entry *) bh->b_data;		}		if (i * sizeof(struct dir_entry) >= dir->i_size) {			de->inode=0;			dir->i_size = (i + 1) * sizeof(struct dir_entry);			dir->i_mtime = file_datetime;
			dir->i_dirt = 1;		}		if (!de->inode) {			for (i = 0; i < NAME_LEN ; i++)				de->name[i] = (i < namelen)? get_gs_byte(name + i) : 0;			bh->b_dirt = 1;			*res_dir = de;			return bh;		}		de++;		i++;	}	brelse(bh);	return NULL;}struct m_inode * get_dir(const char * pathname){
	struct m_inode     * inode;	struct buffer_head * bh;
	struct dir_entry   * de;
	const  char        * thisname;
	char                 c;	int                  idev,inr,namelen;
	int					 i;	if ((!current_root) || (!current_root->i_count) || (!current_pwd) || (!current_pwd->i_count))		return NULL;	if ((c = get_gs_byte(pathname)) == '\\') {		inode = current_root;		pathname++;
		for (i = 0; i <= current_root_pathlength; i++)
			current_path[i] = current_root_path[i];
		current_pathlength  = current_root_pathlength;	} else if (c) {		inode = current_pwd;
		for (i = 0; i <= current_pwd_pathlength; i++)
			current_path[i] = current_pwd_path[i];
		current_pathlength  = current_pwd_pathlength;
	}	else		return NULL;	
	inode->i_count++;	while (1) {		thisname = pathname;		if (!S_ISDIR(inode->i_mode)) {			iput(inode);			return NULL;		}		for(namelen = 0 ; (c = get_gs_byte(pathname++)) && (c != '\\') ; namelen++)
			current_path[current_pathlength + namelen + 1] = c;
		current_path[current_pathlength + namelen + 1] = c;
		if (!c)			return inode;		if (!(bh = find_entry(inode,thisname,namelen,&de))) {			iput(inode);			return NULL;		}		inr = de->inode;		idev = inode->i_dev;		brelse(bh);		iput(inode);

		if ((current_path[current_pathlength + 1] == '.') && (current_path[current_pathlength + 2] == '\\'))
		{}
		else if ((current_path[current_pathlength + 1] == '.') && (current_path[current_pathlength + 2] == '.') && 
			     (current_path[current_pathlength + 3] == '\\'))
			current_pathlength = current_path[current_pathlength];
		else
		{
			current_path[current_pathlength + namelen + 1] = current_pathlength;
			current_pathlength = current_pathlength + namelen + 1;
		}
		if (!(inode = iget(idev,inr)))			return NULL;	}
	return NULL;}struct m_inode * dir_namei(const char * pathname,	int * namelen, const char ** name){	struct m_inode * dir;
	const char     * basename;
	char             c;	if (!(dir = get_dir(pathname)))		return NULL;	basename = pathname;	while ((c = get_gs_byte(pathname++)) != 0)		if (c == '\\')			basename = pathname;
	*namelen = (int)(pathname - basename - 1);	*name    = basename;	return dir;}struct m_inode * namei(const char * pathname){	struct m_inode     * dir;	struct buffer_head * bh;	struct dir_entry   * de;	const char         * basename;
	int                  idev,inr,namelen;
	if (!(dir = dir_namei(pathname,&namelen,&basename)))		return NULL;	if (!namelen)			/* special case: '/usr/' etc */		return dir;	bh = find_entry(dir,basename,namelen,&de);	if (!bh) {		iput(dir);		return NULL;	}	idev = dir->i_dev;
	inr = de->inode;	brelse(bh);	iput(dir);

	if ((current_path[current_pathlength + 1] == '.') && (current_path[current_pathlength + 2] == 0))
	{}
	else if ((current_path[current_pathlength + 1] == '.') && (current_path[current_pathlength + 2] == '.') && 
			 (current_path[current_pathlength + 3] == 0))
		current_pathlength = current_path[current_pathlength];
	else
	{
		current_path[current_pathlength + namelen + 1] = current_pathlength;
		current_pathlength = current_pathlength + namelen + 1;
	}
	dir = iget(idev,inr);	return dir;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -