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)
                {

Reply via email to