[comp.sys.sgi] tftp from C

burow@cernvax.cern.ch (burkhard burow) (06/04/91)

I have some hardware with which I can only communicate via tftp. Communicating
with this hw is part of a larger user interface. The question is:

How can I best call tftp from within a C program?

My forebearers (sp?) threw together a system where each access spawns an 
instance of tftp via e.g.
	:
ierr = system("tftp 133.178.32.111 <input_instruction_file >output_log");
        :

I'd like to make this a bit faster, more elegant, check the tftp output without
having to poll the output_log file, ...

I know of two soln.'s:

i) Call the internal routines of tftp directly. My copy of 
Unix_Network_Programming includes code for a tftp implementation. I could type
this in and hope for the best but best would be ...

              COULD SGI PROVIDE ME WITH THE SOURCE CODE TO TFTP?

ii) I have used Mark Bartelt's (mark@cita.toronto.edu) code which he posted
~month ago, modified and appended below, to spawn tftp once and then feed it
input and obtain the output within a C program. Feeding it input works, but the
output seems to be buffered, so cannot observe tftp's response to individual
commands. [In the example below I've put in some debug code, and yes I know
that if I don't read out tftp's output I've got to feed it to a file or
/dev/null so that it doesn't block.]

QQQQ: Is there some way to spawn a process and force it's stdout buffer to be
unbuffered? 


I think I prefer tftp source code, or equivalently the 'library', as a soln. to
this problem, but an answer to the second question could be useful in other
situations. [i.e. where a utility's source is not readily obtainable.]


Thanks for any and all info. or pointers. I will forward info. to those who
request.

burkhard

----------------------cut here for mark's code---------------------------------



/*
 *	Parent process -- reads a line from stdin, sends it to
 *	child, reads a line back from child, sends it to stdout
 */

#include <stdio.h>

#define PCR	p_to_c[0]	/* parent-to-child pipe, read fd */
#define PCW	p_to_c[1]	/* parent-to-child pipe, write fd */
#define CPR	c_to_p[0]	/* child-to-parent pipe, read fd */
#define CPW	c_to_p[1]	/* child-to-parent pipe, write fd */

#define BUFSIZE 200

main()
{
	int	p_to_c[2];
	int	c_to_p[2];
	int	fk;
	FILE *	to_child;
	FILE *	from_child;
	char	buf[BUFSIZE];

	pipe(p_to_c);
	pipe(c_to_p);

	if ( (fk=fork()) == 0 ) {	/* Child process only */
		dup2(PCR,0);
		dup2(CPW,1);
	}

	close(PCR);			/* Both processes */
	close(CPW);

	if ( fk == 0 ) {		/* Child process only */
		close(PCW);
		close(CPR);
/*		execl("./sqrt","sqrt",0);*/
		execl("/usr/bsd/tftp","tftp",0);
/*		execl("/usr/local/bin/less","less",0);*/
		fprintf(stderr,"sqrt exec failure\\n");
		exit(-1);
	}

 
	to_child   = fdopen(PCW,"w");	/* Parent process only */
	from_child = fdopen(CPR,"r");
	setlinebuf(to_child);
puts("1");
	while ( fgets(buf,BUFSIZE,stdin) != NULL ) {
puts("2");
		fputs(buf,to_child);
puts("3");
/*		fgets(buf,BUFSIZE,from_child);
puts("4");
		fputs(buf,stdout);
puts("5");*/
{int i; while (i=getc(from_child) != '>') putchar(i);}
	}
puts("6");

	fclose(to_child);
	fclose(from_child);

}

arc@kaibab.wpd.sgi.com (Andrew Cherenson) (06/05/91)

In article <5538@cernvax.cern.ch> burow@cernvax.cern.ch (burkhard burow) writes:
>              COULD SGI PROVIDE ME WITH THE SOURCE CODE TO TFTP?

You can get the source to tftp (and other BSD programs) via anonymous 
ftp from uunet.uu.net in the bsd-sources/usr.bin/tftp directory.
Use -D_BSD_COMPAT and -signed when compiling BSD programs on the IRIS.