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

📄 dasdfmt.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * * dasdfmt.c * *  S390 version *    Copyright (C) 1999,2000 IBM Corporation *    Author(s): Utz Bacher, <utz.bacher@de.ibm.com> * *  Device-in-use-checks by Fritz Elfert, <felfert@to.com> * * Still to do: *   detect non-switch parameters ("dasdfmt -n 170 XY") and complain about them  */#include <unistd.h>#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/ioctl.h>#include <errno.h>#include <getopt.h>#include <limits.h>#include <stdlib.h>#include <string.h>#include <dirent.h>#include <mntent.h>#include "../../../drivers/s390/block/dasd.h" /* uses DASD_PARTN_BITS */#define __KERNEL__ /* we want to use kdev_t and not have to define it */#include <linux/kdev_t.h>#undef __KERNEL__#define EXIT_MISUSE 1#define EXIT_BUSY 2#define TEMPFILENAME "/tmp/ddfXXXXXX"#define TEMPFILENAMECHARS 8  /* 8 characters are fixed in all temp filenames */#define IOCTL_COMMAND 'D' << 8#define SLASHDEV "/dev/"#define PROC_DASD_DEVICES "/proc/dasd/devices"#define DASD_DRIVER_NAME "dasd"#define PROC_LINE_LENGTH 80#define ERR_LENGTH 80#define MAX_FILELEN NAME_MAX+PATH_MAX#define GIVEN_DEVNO 1#define GIVEN_MAJOR 2#define GIVEN_MINOR 4#define CHECK_START 1#define CHECK_END 2#define CHECK_BLKSIZE 4#define CHECK_ALL ~0#define ERRMSG(x...) {fflush(stdout);fprintf(stderr,x);}#define ERRMSG_EXIT(ec,x...) {fflush(stdout);fprintf(stderr,x);exit(ec);}#define CHECK_SPEC_MAX_ONCE(i,str) \	{if (i>1) \		ERRMSG_EXIT(EXIT_MISUSE,"%s: " str " " \			"can only be specified once\n",prog_name);}#define PARSE_PARAM_INTO(x,param,base,str) \	{x=(int)strtol(param,&endptr,base); \	if (*endptr) \		ERRMSG_EXIT(EXIT_MISUSE,"%s: " str " " \			"is in invalid format\n",prog_name);}typedef struct {	int start_unit;	int stop_unit;	int blksize;} format_data_t;char prog_name[]="dasd_format";char tempfilename[]=TEMPFILENAME;voidexit_usage(int exitcode){	printf("Usage: %s [-htvyV] [-b blocksize] <range> <diskspec>\n\n",	       prog_name);	printf("       where <range> is either\n");	printf("           -s start_track -e end_track\n");	printf("       or\n");	printf("           -r start_track-end_track\n");	printf("       and <diskspec> is either\n");	printf("           -f /dev/dasdX\n");	printf("       or\n");	printf("           -n <s390-devnr>\n");	exit(exitcode);}voidget_xno_from_xno(int *devno,kdev_t *major_no,kdev_t *minor_no,int mode){	FILE *file;	int d,rc;	kdev_t mi,ma;	int mi_i,ma_i; /* for scanf :-( */	char line[PROC_LINE_LENGTH];	file=fopen(PROC_DASD_DEVICES,"r");	if (file==NULL)		ERRMSG_EXIT(EXIT_FAILURE,"%s: failed to open " \			PROC_DASD_DEVICES ": %s (do you have the /proc " \			"filesystem enabled?)\n",prog_name,strerror(errno));	fgets(line,sizeof(line),file); /* omit first line */	while (fgets(line,sizeof(line),file)!=NULL) {		rc=sscanf(line,"%X%d%d",&d,&ma_i,&mi_i);		ma=ma_i;		mi=mi_i;		if ( (rc==3) &&			!((d!=*devno)&&(mode&GIVEN_DEVNO)) &&			!((ma!=*major_no)&&(mode&GIVEN_MAJOR)) &&			!((mi!=*minor_no)&&(mode&GIVEN_MINOR)) ) {			*devno=d;			*major_no=ma;			*minor_no=mi;			/* yes, this is a quick exit, but the easiest way */			fclose(file);			return;		}	}	fclose(file);	ERRMSG_EXIT(EXIT_FAILURE,"%s: failed to find device in the /proc " \		"filesystem (are you sure to have the right param line?)\n",		prog_name);}char *get_devname_from_devno(int devno,int verbosity){	kdev_t major_no,minor_no;	kdev_t file_major,file_minor;	struct stat stat_buf;	int rc;	int found;	char *devname;	char tmpname[MAX_FILELEN];	DIR *dp;	struct dirent *direntp;	/**** get minor number ****/	get_xno_from_xno(&devno,&major_no,&minor_no,GIVEN_DEVNO);	/**** get device file ****/	if ((dp=opendir(SLASHDEV)) == NULL)		ERRMSG_EXIT(EXIT_FAILURE,"%s: unable to read " SLASHDEV \			"\n",prog_name);	found=0;	while ((direntp=readdir(dp)) != NULL) {		strcpy(tmpname,SLASHDEV);		strcat(tmpname,direntp->d_name);		rc=stat(tmpname,&stat_buf);		if (!rc) {			file_major=MAJOR(stat_buf.st_rdev);			file_minor=MINOR(stat_buf.st_rdev);			if ((file_major==major_no) && (file_minor==minor_no)) {				found=1;				break;			}		}	}	if (found) {		devname=malloc(strlen(direntp->d_name));		strcpy(devname,tmpname);	}	rc=closedir(dp);	if (rc<0) ERRMSG("%s: unable to close directory " SLASHDEV \		"; continuing\n",prog_name);	if (found)		return devname;	if (verbosity>=1)		printf("I didn't find device node in " SLASHDEV \			"; trying to create a temporary node\n");	/**** get temp file and create device node *****/	rc=mkstemp(tempfilename);	if (rc==-1)		ERRMSG_EXIT(EXIT_FAILURE,"%s: failed to get temporary " \			"filename: %s\n",prog_name,strerror(errno));	close(rc);	rc=unlink(tempfilename);		rc=mknod(tempfilename,S_IFBLK|0600,MKDEV(major_no,minor_no));	if (rc)		ERRMSG_EXIT(EXIT_FAILURE,"%s: failed to create temporary " \			"device node %s: %s\n",prog_name,tempfilename,			strerror(errno));	return tempfilename;}char *check_param(int mode,format_data_t data){	char *s;	if (NULL==(s=malloc(ERR_LENGTH)))		ERRMSG_EXIT(EXIT_FAILURE,"%s: not enough memory.\n",prog_name);	if ((mode&CHECK_START)&&(data.start_unit<0)) {		strcpy(s,"start track must be greater than zero");		goto exit;	}	if ((mode&CHECK_END)&&(data.stop_unit<-1)) {		strcpy(s,"end track must be -1 or greater than zero");		goto exit;	}	if ((mode&CHECK_END)&&(data.start_unit>data.stop_unit)&&		(data.stop_unit!=-1)) {		strcpy(s,"end track must be higher than start track");		goto exit;	}	if ((mode&CHECK_BLKSIZE)&&(data.blksize<1)) {		strcpy(s,"blocksize must be a positive integer");		goto exit;	}	if (mode&CHECK_BLKSIZE) while (data.blksize>0) {		if ((data.blksize%2)&&(data.blksize!=1)) {			strcpy(s,"blocksize must be a power of 2");			goto exit;		}		data.blksize/=2;	}	free(s);	return NULL;exit:	return s;}#define ASK_PRINTOUT printf("Please enter %s",output)#define ASK_GETBUFFER fgets(buffer,sizeof(buffer),stdin)#define ASK_SCANFORNUMBER(var) rc=sscanf(buffer,"%d%c",&var,&c)#define ASK_COMPLAIN_FORMAT if ((rc==2)&&(c=='\n')) rc=1; \	if (rc==-1) rc=1; /* this happens, if enter is pressed */ \	if (rc!=1) printf(" -- wrong input, try again.\n")#define ASK_CHECK_PARAM(mode) str=check_param(mode,params); \		if (str!=NULL) { printf(" -- %s\n",str); rc=0; free(str); }format_data_task_user_for_data(format_data_t params){	char buffer[20]; /* should be enough for inputing track numbers */	char c;	int i,rc;	char *str;	char output[60],o2[12];	i=params.start_unit;	do {		params.start_unit=i;		sprintf(output,"the start track of the range to format " \			"[%d]: ",i);		ASK_PRINTOUT;		ASK_GETBUFFER;		ASK_SCANFORNUMBER(params.start_unit);		ASK_COMPLAIN_FORMAT;		ASK_CHECK_PARAM(CHECK_START);	} while (rc!=1);	i=params.stop_unit;	do {		params.stop_unit=i;		sprintf(output,"the end track of the range to format [");		if (i==-1) sprintf(o2,"END]: "); else			sprintf(o2,"%d]: ",i);		strcat(output,o2);		ASK_PRINTOUT;		ASK_GETBUFFER;		if ( (!strcasecmp(buffer,"end")) ||			(!strcasecmp(buffer,"end\n")) ) {			rc=1;			params.stop_unit=-1;		} else {			ASK_SCANFORNUMBER(params.stop_unit);			ASK_COMPLAIN_FORMAT;			ASK_CHECK_PARAM(CHECK_END);		}	} while (rc!=1);	i=params.blksize;	do {		params.blksize=i;		sprintf(output,"the blocksize of the formatting [%d]: ",i);		ASK_PRINTOUT;		ASK_GETBUFFER;		ASK_SCANFORNUMBER(params.blksize);		ASK_COMPLAIN_FORMAT;		ASK_CHECK_PARAM(CHECK_BLKSIZE);	} while (rc!=1);	return params;}/* Check if the device we are going to format is mounted. * If true, complain and exit. */voidcheck_mounted(int major, int minor){	FILE *f;	int ishift = 0;	struct mntent *ment;	struct stat stbuf;	char line[128];	/* If whole disk to be formatted ... */	if ((minor % (1U << DASD_PARTN_BITS)) == 0) {		/* ... ignore partition-selector */		minor >>= DASD_PARTN_BITS;		ishift = DASD_PARTN_BITS;	}	/*

⌨️ 快捷键说明

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