+struct globals {
+ /* u16 TFTP_ERROR; u16 reason; both network-endian, then error text: */
+ uint8_t error_pkt[4 + 32];
+ char *user_opt;
+ /* used in tftpd_main(), a bit big for stack: */
+ char block_buf[TFTP_BLKSIZE_DEFAULT];
+#if ENABLE_FEATURE_TFTP_PROGRESS_BAR
+ off_t pos;
+ off_t size;
+ const char *file;
+ bb_progress_t pmt;
+#endif
+} FIX_ALIASING;
+#define G (*(struct globals*)&bb_common_bufsiz1)
+struct BUG_G_too_big {
+ char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1];
+};
+#define block_buf (G.block_buf )
+#define user_opt (G.user_opt )
+#define error_pkt (G.error_pkt )
+#define INIT_G() do { } while (0)
+
+#define error_pkt_reason (error_pkt[3])
+#define error_pkt_str (error_pkt + 4)
+
+#if ENABLE_FEATURE_TFTP_PROGRESS_BAR
+static void tftp_progress_update(void)
+{
+ bb_progress_update(&G.pmt, 0, G.pos, G.size);
+}
+static void tftp_progress_init(void)
+{
+ bb_progress_init(&G.pmt, G.file);
+ tftp_progress_update();
+}
+static void tftp_progress_done(void)
+{
+ if (is_bb_progress_inited(&G.pmt)) {
+ tftp_progress_update();
+ bb_putchar_stderr('\n');
+ bb_progress_free(&G.pmt);
+ }
+}
+#else
+# define tftp_progress_init() ((void)0)
+# define tftp_progress_done() ((void)0)
+#endif
+