/*
 *  ntcat.c
 *
 *  Copyright (C) 1995 Martin von Löwis
 */

#include <stdio.h>
#include <getopt.h>
#include <unistd.h>
#include <string.h>
#include "ntfs.h"
#include "config.h"
/* glibc string.h does not define a memcpy prototype */
void* memcpy(void*,const void*,size_t);

char *short_opts="f:o:l:B:";
struct option options[]={
	{"filesystem",1,0,'f'},
	{"offset",1,0,'o'},
	{"size",1,0,'s'},
	{"bias",1,0,'b'}
};

void usage()
{
	fprintf(stderr,"ntcat [-f device] [-o offset] [-l size] [directory/]filename\n");
}

/* print the file ino on stdout */
void ntfs_cat_file(ntfs_inode *ino,int offset,int length)
{
	int position,len;
	char *buf;
	int bufsize;
	position=offset;
	if(length)
		bufsize=length;
	else
		bufsize=8192;
	buf=(char*)malloc(bufsize);
	/* Very large file */
	if(!buf)
	{
		bufsize=8192;
		buf=(char*)malloc(bufsize);
		if(!buf)
		{
			perror("ntcat");
			exit(0);
		}
	}
	/* read from the unnamed data attribute */
	while((len=ntfs_read_attr(ino,AT_DATA,NULL,
		position,buf,bufsize,memcpy))>0)
	{
		write(1,buf,len);
		position+=len;
		length-=len;
		if(length==0)
			break;
	}
	free(buf);
}

/* answer the MFT record number for file name in directory ino */
int ntfs_find_file(ntfs_inode* ino,char *name)
{
	char item[1000];
	if(!ntfs_getdir_byname(ino,name,strlen(name),item))return -1;
	return *(int*)item;
}

int main(int argc,char *argv[])
{
	int c;
	char *device=0;
	int offset=0;
	int length=0;
	char *name;
	ntfs_inode ino;
	int inum;
	int bias=0;

	opterr=1;
	while((c=getopt_long(argc,argv,short_opts,options,NULL))>0)
	switch(c)
	{
		case 'f': device=optarg;break;
		case 'o': offset=strtol(optarg,NULL,0);break;
		case 'l': length=strtol(optarg,NULL,0);break;
		case 'B': bias=strtol(optarg,NULL,0);break;
	}
	name=argv[optind];
	if(!ntfs_open_volume(device,bias,1,0))return 1;
	inum=5;
	/* walk the directory tree */
	do{
		char *next;
		ntfs_init_inode(&ino,the_vol,inum);
		if(!name || !*name)break;
		next=strchr(name,'/');
		if(next){
			*next='\0';
			next++;
		}
		inum=ntfs_find_file(&ino,name);
		if(inum==-1){
			fprintf(stderr,"%s not found\n",name);
			return 1;
		}
		name=next;
	}while(1);
	ntfs_init_inode(&ino,the_vol,inum);
	ntfs_cat_file(&ino,offset,length);
}

