7b4c7a681c
Break libblkid into 4 libraries: libblkid, libuuid, libutil-linux and libfdisk. This should help in later patch updates. Change-Id: I680d9a7feb031e5c29a603e9c58aff4b65826262
155 lines
3.3 KiB
C
155 lines
3.3 KiB
C
|
|
#include "fdiskP.h"
|
|
#include "pathnames.h"
|
|
|
|
#include <ctype.h>
|
|
|
|
/**
|
|
* SECTION: utils
|
|
* @title: Utils
|
|
* @short_description: misc fdisk functions
|
|
*/
|
|
|
|
/*
|
|
* Zeros in-memory first sector buffer
|
|
*/
|
|
int fdisk_init_firstsector_buffer(struct fdisk_context *cxt)
|
|
{
|
|
if (!cxt)
|
|
return -EINVAL;
|
|
|
|
if (!cxt->firstsector || cxt->firstsector_bufsz != cxt->sector_size) {
|
|
/* Let's allocate a new buffer if no allocated yet, or the
|
|
* current buffer has incorrect size */
|
|
if (!cxt->parent || cxt->parent->firstsector != cxt->firstsector)
|
|
free(cxt->firstsector);
|
|
|
|
DBG(CXT, ul_debugobj(cxt, "initialize in-memory first sector "
|
|
"buffer [sector_size=%lu]", cxt->sector_size));
|
|
cxt->firstsector = calloc(1, cxt->sector_size);
|
|
if (!cxt->firstsector)
|
|
return -ENOMEM;
|
|
|
|
cxt->firstsector_bufsz = cxt->sector_size;
|
|
return 0;
|
|
}
|
|
|
|
DBG(CXT, ul_debugobj(cxt, "zeroize in-memory first sector buffer"));
|
|
memset(cxt->firstsector, 0, cxt->firstsector_bufsz);
|
|
return 0;
|
|
}
|
|
|
|
int fdisk_read_firstsector(struct fdisk_context *cxt)
|
|
{
|
|
ssize_t r;
|
|
int rc;
|
|
|
|
assert(cxt);
|
|
assert(cxt->sector_size);
|
|
|
|
rc = fdisk_init_firstsector_buffer(cxt);
|
|
if (rc)
|
|
return rc;
|
|
|
|
assert(cxt->sector_size == cxt->firstsector_bufsz);
|
|
|
|
DBG(CXT, ul_debugobj(cxt, "reading first sector "
|
|
"buffer [sector_size=%lu]", cxt->sector_size));
|
|
|
|
r = lseek(cxt->dev_fd, 0, SEEK_SET);
|
|
if (r == -1)
|
|
{
|
|
DBG(CXT, ul_debugobj(cxt, "failed to seek to first sector %m"));
|
|
return -errno;
|
|
}
|
|
|
|
r = read(cxt->dev_fd, cxt->firstsector, cxt->sector_size);
|
|
|
|
if (r != cxt->sector_size) {
|
|
if (!errno)
|
|
errno = EINVAL; /* probably too small file/device */
|
|
DBG(CXT, ul_debugobj(cxt, "failed to read first sector %m"));
|
|
return -errno;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* fdisk_partname:
|
|
* @dev: device name
|
|
* @partno: partition name
|
|
*
|
|
* Return: allocated buffer with partition name, use free() to deallocate.
|
|
*/
|
|
char *fdisk_partname(const char *dev, size_t partno)
|
|
{
|
|
char *res = NULL;
|
|
const char *p = "";
|
|
int w = 0;
|
|
|
|
if (!dev || !*dev) {
|
|
if (asprintf(&res, "%zd", partno) > 0)
|
|
return res;
|
|
return NULL;
|
|
}
|
|
|
|
w = strlen(dev);
|
|
if (isdigit(dev[w - 1]))
|
|
#ifdef __GNU__
|
|
p = "s";
|
|
#else
|
|
p = "p";
|
|
#endif
|
|
|
|
/* devfs kludge - note: fdisk partition names are not supposed
|
|
to equal kernel names, so there is no reason to do this */
|
|
if (strcmp(dev + w - 4, "disc") == 0) {
|
|
w -= 4;
|
|
p = "part";
|
|
}
|
|
|
|
/* udev names partitions by appending -partN
|
|
e.g. ata-SAMSUNG_SV8004H_0357J1FT712448-part1 */
|
|
if ((strncmp(dev, _PATH_DEV_BYID, sizeof(_PATH_DEV_BYID) - 1) == 0) ||
|
|
strncmp(dev, _PATH_DEV_BYPATH, sizeof(_PATH_DEV_BYPATH) - 1) == 0) {
|
|
p = "-part";
|
|
}
|
|
|
|
if (asprintf(&res, "%.*s%s%zu", w, dev, p, partno) > 0)
|
|
return res;
|
|
|
|
return NULL;
|
|
}
|
|
|
|
#ifdef TEST_PROGRAM
|
|
struct fdisk_label *fdisk_new_dos_label(struct fdisk_context *cxt) { return NULL; }
|
|
struct fdisk_label *fdisk_new_bsd_label(struct fdisk_context *cxt) { return NULL; }
|
|
|
|
int test_partnames(struct fdisk_test *ts, int argc, char *argv[])
|
|
{
|
|
size_t i;
|
|
const char *disk = argv[1];
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
char *p = fdisk_partname(disk, i + 1);
|
|
if (p)
|
|
printf("%zu: '%s'\n", i + 1, p);
|
|
free(p);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
struct fdisk_test tss[] = {
|
|
{ "--partnames", test_partnames, "<diskname>" },
|
|
{ NULL }
|
|
};
|
|
|
|
return fdisk_run_test(tss, argc, argv);
|
|
}
|
|
|
|
#endif
|