/*--------------------------------------------------------------------------*/ /* */ /* */ /* ------------ Bit-Bucket Software, Co. */ /* \ 10001101 / Writers and Distributors of */ /* \ 011110 / Freely Available Software. */ /* \ 1011 / */ /* ------ */ /* */ /* (C) Copyright 1987-96, Bit Bucket Software Co. */ /* */ /* This module was written by Vince Perriello */ /* */ /* BinkleyTerm File Request Failure Message Module */ /* */ /* */ /* For complete details of the licensing restrictions, please refer */ /* to the License agreement, which is published in its entirety in */ /* the MAKEFILE and BT.C, and also contained in the file LICENSE.260. */ /* */ /* USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE */ /* BINKLEYTERM LICENSING AGREEMENT. IF YOU DO NOT FIND THE TEXT OF */ /* THIS AGREEMENT IN ANY OF THE AFOREMENTIONED FILES, OR IF YOU DO */ /* NOT HAVE THESE FILES, YOU SHOULD IMMEDIATELY CONTACT BIT BUCKET */ /* SOFTWARE CO. AT ONE OF THE ADDRESSES LISTED BELOW. IN NO EVENT */ /* SHOULD YOU PROCEED TO USE THIS FILE WITHOUT HAVING ACCEPTED THE */ /* TERMS OF THE BINKLEYTERM LICENSING AGREEMENT, OR SUCH OTHER */ /* AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO. */ /* */ /* */ /* You can contact Bit Bucket Software Co. at any one of the following */ /* addresses: */ /* */ /* Bit Bucket Software Co. FidoNet 1:104/501, 1:343/491 */ /* P.O. Box 460398 AlterNet 7:42/1491 */ /* Aurora, CO 80046 BBS-Net 86:2030/1 */ /* Internet f491.n343.z1.fidonet.org */ /* */ /* Please feel free to contact us at any time to share your comments about */ /* our software and/or licensing policies. */ /* */ /*--------------------------------------------------------------------------*/ /* Include this file before any other includes or defines! */ #include "includes.h" typedef struct { /* MB 93-12-12 PKTRSP */ short ver; short orig_node; short dest_node; short orig_net; short dest_net; short attr; short cost; } PACKED, *PACKED_PTR; #define ATTRIB 129 void Make_Response (char *, int); /* Build a response */ void Make_Response (char *data, int failure) { FILE *Template, *Response; char *dummy_text; char *text; char *failure_text[10]; char resp_filename[80]; char *p, *q, *s; struct tm *tp; time_t ltime; int i; struct _pkthdr45 pkt_hdr; PACKED p_msg; ADDR real_addr; if (Netmail_Session == 2) { text = strchr (data, ' '); if (text != NULL) *text = '\0'; } Template = Response = (FILE *) NULL; dummy_text = NULL; for (i = 0; i < 9; i++) failure_text[i] = NULL; if (((text = calloc (1, 256)) == NULL) || ((dummy_text = calloc (1, 256)) == NULL)) goto resp_failed; (void) time (<ime); tp = localtime (<ime); if ((Template = share_fopen (CURRENT.rq_Template, read_ascii, DENY_WRITE)) == NULL) { (void) got_error (MSG_TXT (M_OPEN_MSG), CURRENT.rq_Template); goto resp_failed; } if (pktrsp) /* MB 93-12-12 PKTRSP */ { invent_pkt_name (resp_filename); /* prepare unique response filename */ (void) sprintf (dummy_text, "%02x", TaskNumber); (void) strncpy (resp_filename, dummy_text, 2); if (failure == 10) { (void) sprintf (dummy_text, "%s%s", PROT.sc_Inbound, resp_filename); assumed = 0; } else (void) sprintf (dummy_text, "%s%s", flag_dir, resp_filename); (void) strcpy (resp_filename, dummy_text); } else { if (alias[assumed].Point != 0) (void) sprintf (resp_filename, "%08hx.RSP", alias[assumed].Point); else (void) sprintf (resp_filename, "%s.RSP", Hex_Addr_Str (&(alias[assumed]))); } if ((Response = fopen (resp_filename, write_binary)) == NULL) { (void) got_error (MSG_TXT (M_OPEN_MSG), resp_filename); goto resp_failed; } if (pktrsp) /* MB 93-12-12 PKTRSP */ { real_addr = remote_addr; if ((pvtnet >= 0) && (remote_addr.Net == (word) pvtnet) && (boss_addr.Zone == remote_addr.Zone) && (remote_addr.Point == 0)) { real_addr.Point = remote_addr.Node; real_addr.Net = boss_addr.Net; real_addr.Node = boss_addr.Node; } /* set up pkt and msg headers */ memset (&pkt_hdr, 0, sizeof (pkt_hdr)); pkt_hdr.orig_zone = alias[assumed].Zone; pkt_hdr.orig_net = p_msg.orig_net = alias[assumed].Net; pkt_hdr.orig_node = p_msg.orig_node = alias[assumed].Node; pkt_hdr.orig_point = alias[assumed].Point; pkt_hdr.dest_zone = remote_addr.Zone; pkt_hdr.dest_net = remote_addr.Net; pkt_hdr.dest_point = remote_addr.Point; p_msg.dest_net = real_addr.Net; p_msg.dest_node = real_addr.Node; pkt_hdr.ver = p_msg.ver = PKTVER; pkt_hdr.subver = 2; pkt_hdr.product = PRDCT_CODE; pkt_hdr.serial = 0; p_msg.attr = ATTRIB; /* write pkt header */ (void) fwrite ((char *) &pkt_hdr, sizeof (struct _pkthdr), 1, Response); /* write msg header */ (void) fwrite ((char *) &p_msg, sizeof (PACKED), 1, Response); /* write date */ (void) sprintf (dummy_text, "%02d %3.3s %02d %02d:%02d:02d", tp->tm_mday, mtext[tp->tm_mon], tp->tm_year, tp->tm_hour, tp->tm_min, tp->tm_sec); (void) fwrite (dummy_text, strlen (dummy_text) + 1, 1, Response); /* write sysop */ (void) fwrite ("Sysop", 6, 1, Response); /* write your name */ (void) fwrite (sysop, strlen (sysop) + 1, 1, Response); /* write subject */ (void) fwrite ("Response to File Request", 25, 1, Response); /* write extended flags */ if (alias[assumed].Zone != remote_addr.Zone) { sprintf (dummy_text, "\001INTL %d:%d/%d %d:%d/%d\r", real_addr.Zone, real_addr.Net, real_addr.Node, alias[assumed].Zone, alias[assumed].Net, alias[assumed].Node); (void) fwrite (dummy_text, strlen (dummy_text), 1, Response); } if (alias[assumed].Point > 0) { sprintf (dummy_text, "\001FMPT %d\r", alias[assumed].Point); (void) fwrite (dummy_text, strlen (dummy_text), 1, Response); } if (real_addr.Point > 0) { sprintf (dummy_text, "\001TOPT %d\r", real_addr.Point); (void) fwrite (dummy_text, strlen (dummy_text), 1, Response); } (void) fwrite ("\r\n\r\n", 4, 1, Response); } while (!feof (Template)) { read_line: e_input[0] = '\0'; if (fgets (text, 254, Template) == NULL) break; if (text[0] == '%' && text[1] == ';') continue; /* Comment at start, no output */ p = text; q = e_input; while (*p) { if (*p == '\n') /* All done if newline seen */ break; if (*p != '%') /* Copy until(unless) we see % */ { *q++ = *p++; continue; } if (*++p == ';') /* If followed by ; just skip */ break; if ((i = parse (p, rspverbs)) == -1) /* Check against arg list */ { *q++ = '%'; /* No match, use the % literal */ continue; } switch (i) { case 1: /* "text" */ if (((i = atoi (p = skip_blanks (&p[4]))) < 1) || (i > 9)) goto read_line; if (!*(p = skip_to_blank (p)) || !*++p) goto read_line; if (failure_text[--i] != NULL) { free (failure_text[i]); failure_text[i] = NULL; } failure_text[i] = s = calloc (1, 1 + strlen (p)); if (s == NULL) goto read_line; while ((*p) && (*p != '\n')) *s++ = *p++; *s++ = '\0'; goto read_line; case 2: /* "date" */ p += 4; (void) sprintf (dummy_text, "%2d-%3s-%02d", tp->tm_mday, mtext[tp->tm_mon], tp->tm_year); scopy: s = dummy_text; ccopy: while (*s) *q++ = *s++; break; case 3: /* "time" */ p += 4; (void) sprintf (dummy_text, "%2d:%02d", tp->tm_hour, tp->tm_min); goto scopy; case 4: /* "bink" */ p += 4; s = ANNOUNCE; goto ccopy; case 5: /* "mynode" */ p += 6; (void) sprintf (dummy_text, "%s", Full_Addr_Str (&(alias[assumed]))); goto scopy; case 6: /* "system" */ p += 6; s = system_name; goto ccopy; case 7: /* "sysop" */ p += 5; s = sysop; goto ccopy; case 8: /* "yrnode" */ p += 6; (void) sprintf (dummy_text, "%s", Full_Addr_Str (&remote_addr)); goto scopy; case 9: /* "request" */ p += 7; s = data; goto ccopy; case 10: /* "status" */ p += 6; (void) strcpy (dummy_text, p); if (failure_text[failure - 1] == NULL) text[0] = '\0'; else (void) strcpy (text, failure_text[failure - 1]); (void) strcat (text, dummy_text); p = text; break; case 11: /* "abort" */ if (*(p = skip_blanks (&p[5]))) /* If there's an argument, */ { if (failure != atoi (p)) /* See if it matches failure */ goto read_line; /* No, keep going. */ } (void) fclose (Response); /* Abort things: Close file, */ Response = NULL; /* Keep track of closed file */ (void) unlink (resp_filename); /* Then delete it */ goto resp_failed; /* And take the failure exit */ case 12: /* "exit" */ if (*(p = skip_blanks (&p[4]))) /* If there's an argument, */ { if (failure != atoi (p)) /* See if it matches failure */ goto read_line; /* No, keep going. */ } goto resp_done; /* A match, close the file */ case 13: /* "line" */ if ((!(*(p = skip_blanks (&p[4])))) || (failure != atoi (p))) /* If argument doesn't match, */ goto read_line; /* throw out line, keep going. */ if (*(p = skip_to_blank (p))) /* If there's any text, */ { (void) strcpy (text, ++p); /* Copy rest of line down */ p = text; /* Move pointer to front */ } break; } /* End switch */ } /* End while *p */ *q++ = '\r'; *q++ = '\n'; *q = '\0'; i = (int) (q - e_input); (void) fwrite (e_input, (unsigned int) i, 1, Response); } /* End while !feof (Template) */ resp_done: (void) strcpy (data, resp_filename); (void) fclose (Template); Template = NULL; /* write the final null *//* MB 93-12-12 PKTRSP */ if (pktrsp) (void) fwrite ("\r\n\r\n\0\0\0", 7, 1, Response); (void) fclose (Response); Response = NULL; goto cleanup; resp_failed: *data = '\0'; if (Response != NULL) (void) fclose (Response); if (Template != NULL) (void) fclose (Template); cleanup: for (i = 0; i < 9; i++) { if (failure_text[i] != NULL) { free (failure_text[i]); failure_text[i] = NULL; } } if (text != NULL) free (text); if (dummy_text != NULL) free (dummy_text); return; }