Am Montag, 24. Juli 2006 12:17 schrieb Olaf Dabrunz: > I see. > > And I guess opsi will take care the pipe is only created when that > specific machine needs to boot over the network, e.g. when you want to > install or reinstall it. exactly > > It would be good to have this information in the manpage of atftpd. I > would suggest including the following: > > - a description of the FIFO feature ("you can use named pipes/FIFOs > in addition to files") > - how to use it ("it can be used on the tftp server side to tell the > clients (separately, if you want) to boot from network or to boot > from their fallback boot method") > - your example > - it may or may not be a good idea to mention that opsi uses this > feature ("opsi uses this to provide...") > > A patch that contains both the documentation and the code would be much > easier to consider. here it is. > > Regards,
best regards, -- Jan Schneider uib umwelt informatik büro gmbh Bonifaziusplatz 1B 55118 Mainz Tel. 06131 / 27561-20 Fax 06131 / 27561-22 E-Mail: [EMAIL PROTECTED] Internet: www.uib.de
diff -urN atftpd-0.7.dfsg/atftpd.8 atftpd-0.7.dfsg-fifo/atftpd.8 --- atftpd-0.7.dfsg/atftpd.8 2004-02-13 05:03:12.000000000 +0100 +++ atftpd-0.7.dfsg-fifo/atftpd.8 2006-07-25 11:31:11.000000000 +0200 @@ -240,6 +240,35 @@ specification. Note that this is not the same as RFC2090. PXE compliant boot implements mtftp, not RFC2090. +.SH FIFO +The atftpd server provides the ability to communicate with other +processes using named pipes / FIFOs. In addition to files you can +place FIFOs into the specified root directory which atftpd will open +for reading on a client request and serve the content to the client. +This feature can be used on the tftp server side to tell the clients +(separately, if you want) to boot from network or to boot from their +fallback boot method. + +\fBExample\fR + + #!/usr/bin/perl + use POSIX; + my $pipe = "/tftpboot/linux/pxelinux.cfg/01-00-01-02-03-04-05"; + # create fifo + POSIX::mkfifo($pipe, 0644) or + die("cannot create Pipe $pipe: $!\\n"); + # open pipe + sysopen(FIFO, $pipe, O_WRONLY, 0644); + # write boot configuration + print FIFO "default linux\\r\\n"; + print FIFO "label linux\\r\\n"; + print FIFO " kernel vmlinuz\\r\\n"; + print FIFO " append ramdisk_size=64000 init=/etc/init initrd=initrd\\r\\n"; + close(FIFO); + # delete pipe + unlink($pipe); + + .SH SEE ALSO .BR inetd (8), hosts_access (5), libpcre (7), RFC1350, RFC2090, RFC2347, RFC2348, RFC2349 and pxespec.pdf. diff -urN atftpd-0.7.dfsg/tftp_def.h atftpd-0.7.dfsg-fifo/tftp_def.h --- atftpd-0.7.dfsg/tftp_def.h 2004-02-13 04:16:09.000000000 +0100 +++ atftpd-0.7.dfsg-fifo/tftp_def.h 2006-06-26 11:32:04.000000000 +0200 @@ -33,6 +33,9 @@ #define S_TIMEOUT 5 /* Server timout. */ #define NB_OF_RETRY 5 +#define FIFO_MAX_SIZE 16384 /* Maximum bytes to read from a named pipe */ + + /* definition to use tftp_options structure */ #define OPT_FILENAME 0 #define OPT_MODE 1 diff -urN atftpd-0.7.dfsg/tftpd_file.c atftpd-0.7.dfsg-fifo/tftpd_file.c --- atftpd-0.7.dfsg/tftpd_file.c 2004-02-18 03:21:47.000000000 +0100 +++ atftpd-0.7.dfsg-fifo/tftpd_file.c 2006-07-04 11:42:11.000000000 +0200 @@ -429,6 +429,9 @@ int prev_file_pos = 0; int temp = 0; + char *fifo_buf = NULL; + int fifo_len = -1; + /* look for mode option */ if (strcasecmp(data->tftp_options[OPT_MODE].value, "netascii") == 0) { @@ -498,6 +501,33 @@ /* To return the size of the file with tsize argument */ fstat(fileno(fp), &file_stat); + if (S_ISFIFO (file_stat.st_mode)) + { + fifo_buf = (char *) malloc(sizeof(char)*FIFO_MAX_SIZE); + + if (fifo_buf == NULL) + { + logger(LOG_ERR, "memory allocation failure"); + return ERR; + } + + /* Reading from named pipe into buffer */ + fifo_len = fread( fifo_buf, 1, sizeof(char)*FIFO_MAX_SIZE, fp ); + if (fifo_len < 0) + { + logger(LOG_ERR, "error reading from named pipe %s", filename); + fclose(fp); + free(fifo_buf); + return ERR; + } + else if (fifo_len >= FIFO_MAX_SIZE) + { + logger(LOG_WARNING, "buffer limit reached while reading from pipe"); + } + file_stat.st_size = fifo_len; + logger(LOG_DEBUG, "Read %d bytes from pipe", fifo_len); + } + /* tsize option */ if ((opt_get_tsize(data->tftp_options) > -1) && !convert) { @@ -714,14 +744,39 @@ break; case S_SEND_DATA: timeout_state = state; + if (fifo_len > -1 && fifo_buf != NULL) + { + /* fifo_buf contains data from pipe */ + if (fifo_len >= data->data_buffer_size - 4) + { + data_size = data->data_buffer_size - 4; + fifo_len -= data_size; + } + else + { + data_size = fifo_len; + /* record the last block number */ + last_block = block_number; + } - data_size = tftp_file_read(fp, tftphdr->th_data, data->data_buffer_size - 4, block_number, - convert, &prev_block_number, &prev_file_pos, &temp); - data_size += 4; /* need to consider tftp header */ + strncpy(tftphdr->th_data, fifo_buf + block_number * (data->data_buffer_size - 4), data_size); - /* record the last block number */ - if (feof(fp)) - last_block = block_number; + if (data_size == fifo_len && last_block == block_number) + { + free(fifo_buf); + fifo_buf = NULL; + } + } + else + { + data_size = tftp_file_read(fp, tftphdr->th_data, data->data_buffer_size - 4, block_number, + convert, &prev_block_number, &prev_file_pos, &temp); + /* record the last block number */ + if (feof(fp)) + last_block = block_number; + } + + data_size += 4; /* need to consider tftp header */ if (multicast) {