/* Utility program used during pcnfd installation. Adds an export line for
   /var/spool/pcnfs to /etc/exports, but only if necessary. */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>

char pcnfsdir[] = "/var/spool/pcnfs";
char exports[] = "/etc/exports";

main()
{
	FILE *fp;
	int error;
	char exportdir[MAXPATHLEN], buf[1012];
	
	if(!(fp = fopen(exports, "r+"))) {
		perror("fopen");
		return -1;
	} 

	/* For each exported directory, <exportdir>, loop through /var/spool/pcnfs and it's ancestors,
	   looking for a match with <exportdir>. NOTE that user may enter links in /etc/exports,
	   hence we looks for matches by comparing inodes, rather than symbolically. */

	while(fgets(exportdir, sizeof(exportdir), fp)) {
		if(*exportdir != '#') {
			struct stat dirst;
			char *ptr;
			char tmpbuf[MAXPATHLEN];

			/* null terminate first field (which is exported path name) */
			for(ptr=exportdir;*ptr && *ptr != '\t' && *ptr != ' ' && *ptr != '\n';ptr++);
			*ptr = 0;

			if(stat(exportdir, &dirst)) {
				perror("stat");
				return -1;
			}

			/* 	Special case root directory, because it won't be
				handled by the directory stripping code below. */
			if(!strcmp(exportdir, "/"))
				return 0;

			strcpy(tmpbuf, pcnfsdir);

			while(*tmpbuf) {
				struct stat st;
				
				if(stat(tmpbuf, &st)) {
					perror("stat");
					return -1;
				}
				if(st.st_ino == dirst.st_ino) {
#ifdef TESTING
					printf("got it! %s.\n", tmpbuf);
					printf("%s is on device: %d\n", exportdir, dirst.st_dev);
#endif
					return 0;
				}

				/* chop off last directory entry. */
				ptr = tmpbuf + strlen(tmpbuf) - 1;
				while(*ptr && *ptr != '/')
					ptr--;
				if(*ptr)
					*ptr = 0;
			}

		}
	}

	fprintf(fp, "%s\n", pcnfsdir);

	fclose(fp);

	sprintf(buf, "/usr/etc/exportfs %s\n", pcnfsdir);
	error = system(buf);
#ifdef TESTING
	fprintf(stderr, "system returned 0x%d\n", error);
#endif

	return 0;
}



