FreeBSD/lib/libcam/camlib.c
/*
 * Take a device name or path passed in by the user, and attempt to figure
 * out the device name and unit number.  Some possible device name formats are:
 * /dev/foo0
 * foo0
 * nfoo0
 *
 * Some peripheral drivers create separate device nodes with 'n' prefix for
 * non-rewind operations.  Currently only sa(4) tape driver has this feature.
 * We extract pure peripheral name as device name for this special case.
 *
 * Input parameters:  device name/path, length of devname string
 * Output:            device name, unit number
 * Return values:     returns 0 for success, -1 for failure
 */
Take a device name or path passed in by the user, and attempt to figure
out the device name and unit number.  Some possible device name formats are:
/dev/foo0
foo0
nfoo0

Some peripheral drivers create separate device nodes with 'n' prefix for
non-rewind operations.  Currently only sa(4) tape driver has this feature.
We extract pure peripheral name as device name for this special case.

Input parameters:  device name/path, length of devname string
Output:            device name, unit number
Return values:     returns 0 for success, -1 for failure
Take a device name or path passed in by the user and attempt to figure out the device name and unit number . Some possible device name formats are : / dev / foo0 foo0 nfoo0 Some peripheral drivers create separate device nodes with ' n ' prefix for non - rewind operations . Currently only sa ( 4 ) tape driver has this feature . We extract pure peripheral name as device name for this special case . Input parameters : device name / path length of devname string Output : device name unit number Return values : returns 0 for success - 1 for failure
int
cam_get_device(const char *path, char *dev_name, int devnamelen, int *unit)
{
	char *func_name = "cam_get_device";
	char *tmpstr, *tmpstr2;
	char *newpath;
	int unit_offset;
	int i;
	if (path == NULL) {
		snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
			 "%s: device pathname was NULL", func_name);
		return(-1);
	}
	newpath = (char *)strdup(path);
	tmpstr = newpath;
	if (*tmpstr == '/') {
		tmpstr2 = tmpstr;
		tmpstr = strrchr(tmpstr2, '/');
		if ((tmpstr != NULL) && (*tmpstr != '\0'))
			tmpstr++;
	}
	if (*tmpstr == '\0') {
		snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
			 "%s: no text after slash", func_name);
		free(newpath);
		return(-1);
	}
	if (*tmpstr == 'n' || *tmpstr == 'e') {
		for (i = 0; i < sizeof(nonrewind_devs)/sizeof(char *); i++) {
			int len = strlen(nonrewind_devs[i]);
			if (strncmp(tmpstr + 1, nonrewind_devs[i], len) == 0) {
				if (isdigit(tmpstr[len + 1])) {
					tmpstr++;
					break;
				}
			}
		}
	}
	if (strlen(tmpstr) < 2) {
		snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
			 "%s: must have both device name and unit number",
			 func_name);
		free(newpath);
		return(-1);
	}
	if (isdigit(*tmpstr)) {
		snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
			 "%s: device name cannot begin with a number",
			 func_name);
		free(newpath);
		return(-1);
	}
	if (!isdigit(tmpstr[strlen(tmpstr) - 1])) {
		snprintf(cam_errbuf, CAM_ERRBUF_SIZE,
			 "%s: unable to find device unit number", func_name);
		free(newpath);
		return(-1);
	}
	for (unit_offset = 1;
	    (unit_offset < (strlen(tmpstr)))
	    && (isdigit(tmpstr[strlen(tmpstr) - unit_offset])); unit_offset++);
	unit_offset--;
	*unit = atoi(&tmpstr[strlen(tmpstr) - unit_offset]);
	tmpstr[strlen(tmpstr) - unit_offset] = '\0';
	strlcpy(dev_name, tmpstr, devnamelen);
	free(newpath);
	return(0);
}
int cam_get_device ( const char * path , char * dev_name , int devnamelen , int * unit ) { char * func_name = " " ; char * tmpstr , * tmpstr2 ; char * newpath ; int unit_offset ; int i ; if ( path == NULL ) { snprintf ( cam_errbuf , CAM_ERRBUF_SIZE , " " , func_name ) ; return ( -1 ) ; } newpath = ( char * ) strdup ( path ) ; tmpstr = newpath ; if ( * tmpstr == ' ' ) { tmpstr2 = tmpstr ; tmpstr = strrchr ( tmpstr2 , ' ' ) ; if ( ( tmpstr != NULL ) && ( * tmpstr != ' \0 ' ) ) tmpstr ++ ; } if ( * tmpstr == ' \0 ' ) { snprintf ( cam_errbuf , CAM_ERRBUF_SIZE , " " , func_name ) ; free ( newpath ) ; return ( -1 ) ; } if ( * tmpstr == ' ' || * tmpstr == ' ' ) { for ( i = 0 ; i < sizeof ( nonrewind_devs ) / sizeof ( char * ) ; i ++ ) { int len = strlen ( nonrewind_devs [ i ] ) ; if ( strncmp ( tmpstr + 1 , nonrewind_devs [ i ] , len ) == 0 ) { if ( isdigit ( tmpstr [ len + 1 ] ) ) { tmpstr ++ ; break ; } } } } if ( strlen ( tmpstr ) < 2 ) { snprintf ( cam_errbuf , CAM_ERRBUF_SIZE , " " , func_name ) ; free ( newpath ) ; return ( -1 ) ; } if ( isdigit ( * tmpstr ) ) { snprintf ( cam_errbuf , CAM_ERRBUF_SIZE , " " , func_name ) ; free ( newpath ) ; return ( -1 ) ; } if ( ! isdigit ( tmpstr [ strlen ( tmpstr ) - 1 ] ) ) { snprintf ( cam_errbuf , CAM_ERRBUF_SIZE , " " , func_name ) ; free ( newpath ) ; return ( -1 ) ; } for ( unit_offset = 1 ; ( unit_offset < ( strlen ( tmpstr ) ) ) && ( isdigit ( tmpstr [ strlen ( tmpstr ) - unit_offset ] ) ) ; unit_offset ++ ) ; unit_offset -- ; * unit = atoi ( & tmpstr [ strlen ( tmpstr ) - unit_offset ] ) ; tmpstr [ strlen ( tmpstr ) - unit_offset ] = ' \0 ' ; strlcpy ( dev_name , tmpstr , devnamelen ) ; free ( newpath ) ; return ( 0 ) ; }
Take a device name or path passed in by the user, and attempt to figure
 out the device name and unit number.
Take a device name or path passed in by the user and attempt to figure out the device name and unit number .
/*
	 * We can be rather destructive to the path string.  Make a copy of
	 * it so we don't hose the user's string.
	 */ /*
	 * Check to see whether we have an absolute pathname.
	 */ /*
	 * Check to see whether the user has given us a nonrewound tape
	 * device.
	 */ /*
	 * We should now have just a device name and unit number.
	 * That means that there must be at least 2 characters.
	 * If we only have 1, we don't have a valid device name.
	 */ /*
	 * If the first character of the string is a digit, then the user
	 * has probably given us all numbers.  Point out the error.
	 */ /*
	 * At this point, if the last character of the string isn't a
	 * number, we know the user either didn't give us a device number,
	 * or he gave us a device name/number format we don't recognize.
	 */ /*
	 * Attempt to figure out where the device name ends and the unit
	 * number begins.  As long as unit_offset is at least 1 less than
	 * the length of the string, we can still potentially have a device
	 * name at the front of the string.  When we get to something that
	 * isn't a digit, we've hit the device name.  Because of the check
	 * above, we know that this cannot happen when unit_offset == 1.
	 * Therefore it is okay to decrement unit_offset -- it won't cause
	 * us to go past the end of the character array.
	 */ /*
	 * Grab the unit number.
	 */ /*
	 * Put a null in place of the first number of the unit number so
	 * that all we have left is the device name.
	 */ /* Clean up allocated memory */