/*
 * nulf.c
 *
 * This program creates an empty file of specified size.
 *
 * Usage:
 *   nulf filename size[kmg]
 *
 * 
 * (c) 2003 by Michal Wojciechowski <odyniec(at)odyniec.fdns.net>
 *
 */

#define _FILE_OFFSET_BITS  64

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>

/* file size multipliers */
#define KILOBYTE	1024LL
#define MEGABYTE	(1024 * KILOBYTE)
#define GIGABYTE	(1024 * MEGABYTE)

/* default file permissions */
#define PERM 	(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | \
		S_IROTH | S_IWOTH)

/* select the appropriate multiplier */
int mul(char c)
{
	switch (c) {
		case 'k': case 'K':
			return KILOBYTE;
		case 'm': case 'M':
			return MEGABYTE;
		case 'g': case 'G':
			return GIGABYTE;
	}

	return 1;
}

int main(int argc, char *argv[])
{
	int fd;
	int a;
	off_t size;
	char c;

	if (argc < 3) {
		printf("Usage: %s filename size[kmg]\n", argv[0]);
		printf("Use the suffix \"k\", \"m\" or \"g\" for "
			"kilo-, mega- or gigabytes.\n");
		exit(0);
	}
	
	if ((a = sscanf(argv[2], "%lld%c", &size, &c)) < 1) {
		fprintf(stderr, "%s: bad arguments\n", argv[0]);
		exit(1);
	}

	if ((fd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC,
			PERM)) < 0) {
		perror(argv[0]);
		exit(1);
	}

	if (a == 2) 
		size *= mul(c);
	if (lseek(fd, size-1, SEEK_SET) < 0) {
		perror(argv[0]);
		exit(1);
	}

	if (write(fd, "\0", 1) != 1) {
		perror(argv[0]);
		exit(1);
	}

	close(fd);
	
	exit(0);
}

