/***************************************************************************** * AreaFix for HTICK (FTN Ticker / Request Processor) ***************************************************************************** * Copyright (C) 1998-2000 * * Max Levenkov * * Fido: 2:5000/117 * Internet: sackett@mail.ru * * Novosibirsk, West Siberia, Russia * * This file is part of HTICK, which is based on HPT by Matthias Tichy, * 2:2432/605.14 2:2433/1245, mtt@tichy.de * * HTICK is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2, or (at your option) any * later version. * * HTICK is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HTICK; see the file COPYING. If not, write to the Free * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. ***************************************************************************** * $Id: areafix.c,v 1.70.2.5 2003/02/04 19:18:16 stas_degteff Exp $ *****************************************************************************/ #include #include #include #include #include #if ((!(defined(_MSC_VER) && (_MSC_VER >= 1200)) ) && (!defined(__TURBOC__))) #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include unsigned char RetFix; char *hpt_stristr(char *str, char *find); char *errorRQ(char *line) { char *report = NULL, err[] = "Error line"; xscatprintf(&report,"%s %s\r", line, err); return report; } int subscribeCheck(s_filearea area, s_message *msg, s_link *link) { unsigned int i; int found = 0; for (i = 0; iorigAddr, area.downlinks[i]->link->hisAka)==0) return 0; } if (area.group) { if (link->numAccessGrp > 0) { for (i = 0; i < link->numAccessGrp; i++) if (strcmp(area.group, link->AccessGrp[i]) == 0) found = 1; } if (config->numPublicGroup > 0) { for (i = 0; i < config->numPublicGroup; i++) if (strcmp(area.group, config->PublicGroup[i]) == 0) found = 1; } } else found = 1; if (found == 0) return 2; if (area.hide) return 3; return 1; } int subscribeAreaCheck(s_filearea *area, s_message *msg, char *areaname, s_link *link) { int rc=4; if (!areaname) return rc; if (patimat(area->areaName,areaname)==1) { rc=subscribeCheck(*area, msg, link); // 0 - already subscribed // 1 - need subscribe // 2 - no access group // 3 - area is hidden if (area->mandatory) rc = 2; } else rc = 4; // this is another area return rc; } void addlink(s_link *link, s_filearea *area) { s_arealink *arealink; area->downlinks = srealloc(area->downlinks, sizeof(s_arealink*)*(area->downlinkCount+1)); area->downlinks[area->downlinkCount] = (s_arealink*)scalloc(1, sizeof(s_arealink)); area->downlinks[area->downlinkCount]->link = link; arealink = area->downlinks[area->downlinkCount]; if (link->numOptGrp > 0) { // default set export on, import on, mandatory off arealink->export = 1; arealink->import = 1; arealink->mandatory = 0; if (grpInArray(area->group,link->optGrp,link->numOptGrp)) { arealink->export = link->export; arealink->import = link->import; arealink->mandatory = link->mandatory; } } else { arealink->export = link->export; arealink->import = link->import; arealink->mandatory = link->mandatory; } if (area->mandatory) arealink->mandatory = 1; if (link->level < area->levelread) arealink->export=0; if (link->level < area->levelwrite) arealink->import=0; // paused link can't receive mail if ((link->Pause & FPAUSE) == FPAUSE) arealink->export = 0; area->downlinkCount++; } void removelink(s_link *link, s_filearea *area) { unsigned int i; s_link *links; for (i=0; i < area->downlinkCount; i++) { links = area->downlinks[i]->link; if (addrComp(link->hisAka, links->hisAka)==0) break; } free(area->downlinks[i]); area->downlinks[i] = area->downlinks[area->downlinkCount-1]; area->downlinkCount--; } char *unlinked(s_message *msg, s_link *link) { unsigned int i, rc, n; char *report=NULL; s_filearea *area; area=config->fileAreas; xscatprintf(&report, "Unlinked areas to %s\r\r", aka2str(link->hisAka)); for (i=n=0; ifileAreaCount; i++) { rc=subscribeCheck(area[i], msg, link); if (rc == 1) { xscatprintf(&report, " %s\r", area[i].areaName); n++; } } xscatprintf(&report, "\r%u areas unlinked\r", n); w_log( '8', "FileFix: unlinked fileareas list sent to %s", aka2str(link->hisAka)); return report; } char *list(s_message *msg, s_link *link) { unsigned int i,j,active,avail,rc,desclen; unsigned int *areaslen; unsigned int maxlen; char *report=NULL; int readdeny, writedeny; areaslen = smalloc(config->fileAreaCount * sizeof(int)); maxlen = 0; for (i=0; i< config->fileAreaCount; i++) { areaslen[i]=strlen(config->fileAreas[i].areaName); if (areaslen[i]>maxlen) maxlen = areaslen[i]; } xscatprintf(&report, "Available fileareas for %s\r\r", aka2str(link->hisAka)); for (i=active=avail=0; i< config->fileAreaCount; i++) { rc=subscribeCheck(config->fileAreas[i],msg, link); if (rc < 2) { if (config->fileAreas[i].description!=NULL) desclen=strlen(config->fileAreas[i].description); else desclen=0; if (rc==0) { readdeny = readCheck(&config->fileAreas[i], link); writedeny = writeCheck(&config->fileAreas[i], &(link->hisAka)); if (!readdeny && !writedeny) xstrcat(&report,"& "); else if (writedeny) xstrcat(&report,"+ "); else xstrcat(&report,"* "); active++; avail++; } else { xstrcat(&report," "); avail++; } xstrcat(&report, config->fileAreas[i].areaName); if (desclen!=0) { xstrcat(&report," "); for (j=0;j<(maxlen)-areaslen[i];j++) xstrcat(&report,"."); xstrcat(&report," "); xstrcat(&report,config->fileAreas[i].description); } xstrcat(&report,"\r"); } } xscatprintf(&report, "\r '+' You are receiving files from this area.\r '*' You can send files to this file echo.\r '&' You can send and receive files.\r\r%i areas available for %s, %i areas active\r", avail, aka2str(link->hisAka), active); w_log( LL_AREAFIX, "FileFix: list sent to %s", aka2str(link->hisAka)); nfree(areaslen); return report; } char *linked(s_message *msg, s_link *link, int action) { unsigned int i, n, rc; char *report=NULL; int readdeny, writedeny; if ((link->Pause & FPAUSE) == FPAUSE) xscatprintf(&report, "\rPassive fileareas on %s\r\r", aka2str(link->hisAka)); else xscatprintf(&report, "\rActive fileareas on %s\r\r", aka2str(link->hisAka)); for (i=n=0; ifileAreaCount; i++) { rc=subscribeCheck(config->fileAreas[i], msg, link); if (rc==0) { if (action == 1) { readdeny = readCheck(&config->fileAreas[i], link); writedeny = writeCheck(&config->fileAreas[i], &(link->hisAka)); if (!readdeny && !writedeny) xstrcat(&report,"& "); else if (writedeny) xstrcat(&report,"+ "); else xstrcat(&report,"* "); } else { xstrcat(&report," "); } xstrcat(&report, config->fileAreas[i].areaName); xstrcat(&report, "\r"); n++; } } if (action == 1) xscatprintf(&report, "\r '+' You are receiving files from this area.\r '*' You can send files to this file echo.\r '&' You can send and receive files.\r\r%u areas linked for %s\r", n, aka2str(link->hisAka)); else xscatprintf(&report, "\r%u areas linked\r", n); return report; } char *help(s_link *link) { FILE *f; int i=1; char *help = NULL; long endpos; if (config->filefixhelp!=NULL) { if ((f=fopen(config->filefixhelp,"r")) == NULL) { if (!quiet) fprintf(stderr,"FileFix: cannot open help file \"%s\"\n", config->filefixhelp); return NULL; } fseek(f,0l,SEEK_END); endpos=ftell(f); help=(char*) scalloc((size_t) endpos + 1,sizeof(char)); fseek(f,0l,SEEK_SET); endpos = fread(help,1,(size_t) endpos,f); for (i=0; ihisAka)); return help; } return NULL; } char *available(s_link *link) { FILE *f; unsigned int j=0, found; unsigned int k; char *report = NULL, *line, *token, *running, linkAka[SIZE_aka2str]; s_link *uplink=NULL; ps_arealist al; for (j = 0; j < config->linkCount; j++) { uplink = &(config->links[j]); found = 0; for (k = 0; k < link->numAccessGrp && uplink->LinkGrp; k++) if (strcmp(link->AccessGrp[k], uplink->LinkGrp) == 0) found = 1; if ((uplink->forwardFileRequests && uplink->forwardFileRequestFile) && ((uplink->LinkGrp == NULL) || (found != 0))) { if ((f=fopen(uplink->forwardFileRequestFile,"r")) == NULL) { w_log(LL_AREAFIX, "Filefix: cannot open forwardFileRequestFile \"%s\": %s", uplink->forwardFileRequestFile, strerror(errno)); return report; } xscatprintf(&report, "Available File List from %s:\r", aka2str(uplink->hisAka)); al = newAreaList(); while ((line = readLine(f)) != NULL) { line = trimLine(line); if (line[0] != '\0') { running = line; token = strseparate(&running, " \t\r\n"); addAreaListItem(al,0,token,running); } nfree(line); } fclose(f); if(al->count) { sortAreaList(al); line = formatAreaList(al,78,NULL); xstrcat(&report,"\r"); xstrcat(&report,line); nfree(line); } freeAreaList(al); xscatprintf(&report, " %s\r\r",print_ch(77,'-')); // warning! do not ever use aka2str twice at once! sprintf(linkAka, "%s", aka2str(link->hisAka)); w_log(LL_AREAFIX, "Filefix: Available File List from %s sent to %s", aka2str(uplink->hisAka), linkAka); } } if (report==NULL) { xstrcat(&report, "\r no links for creating Available File List\r"); w_log(LL_AREAFIX, "Filefix: no links for creating Available File List"); } return report; } int changeconfig(char *fileName, s_filearea *area, s_link *link, int action) { FILE *f_conf; char *cfgline = NULL, *line = NULL, *token = NULL, *areaName = NULL, *tmpPtr =NULL; long endpos, cfglen; long strbeg = 0, strend = -1; areaName = area->areaName; if (init_conf(fileName)) return 1; while ((cfgline = configline()) != NULL) { line = sstrdup(cfgline); line = trimLine(line); line = stripComment(line); if (line[0] != 0) { tmpPtr = line = shell_expand(line); token = strseparate(&tmpPtr, " \t"); if (stricmp(token, "filearea")==0) { token = strseparate(&tmpPtr, " \t"); if (stricmp(token, areaName)==0) { fileName = sstrdup(getCurConfName()); strend = get_hcfgPos(); break; } } } strbeg = get_hcfgPos(); nfree(cfgline); nfree(line); } close_conf(); nfree(line); if (strend == -1) { nfree(cfgline); nfree(fileName); return 1; // impossible } if ((f_conf=fopen(fileName,"r+b")) == NULL) { if (!quiet) fprintf(stderr, "FileFix: cannot open config file %s \n", fileName); nfree(cfgline); nfree(fileName); return 1; } nfree(fileName); fseek(f_conf, 0L, SEEK_END); endpos = ftell(f_conf); cfglen = endpos - strend; line = (char*) smalloc((size_t) cfglen+1); fseek(f_conf, strend, SEEK_SET); cfglen = fread(line, sizeof(char), cfglen, f_conf); line[cfglen]='\0'; fseek(f_conf, strbeg, SEEK_SET); setfsize( fileno(f_conf), strbeg ); switch (action) { case 0: xstrscat(&cfgline, " ", aka2str(link->hisAka), NULL); break; case 1: DelLinkFromString(cfgline, link->hisAka); break; default: break; } fprintf(f_conf, "%s%s%s", cfgline, cfgEol(), line); fclose(f_conf); nfree(line); nfree(cfgline); return 0; } // subscribe if (act==0), unsubscribe if (act==1) int forwardRequestToLink( char *areatag, char *descr, s_link *uplink, s_link *dwlink, int act) { s_message *msg; char *base, pass[]="passthrough"; if (uplink->msg == NULL) { msg = makeMessage(uplink->ourAka, &(uplink->hisAka), config->sysop, uplink->RemoteFileRobotName ? uplink->RemoteFileRobotName : "filefix", uplink->fileFixPwd ? uplink->fileFixPwd : "\x00", 1, config->filefixKillReports); msg->text = createKludges(config->disableTID,NULL, uplink->ourAka, &(uplink->hisAka), versionStr); uplink->msg = msg; } else msg = uplink->msg; if (act==0) { if (getFileArea(config, areatag) == NULL) { base = uplink->fileBaseDir; if (config->createFwdNonPass == 0) uplink->fileBaseDir = pass; // create from own address if (isOurAka(config,dwlink->hisAka)) { uplink->fileBaseDir = base; } autoCreate(areatag, descr, &(uplink->hisAka), &(dwlink->hisAka)); uplink->fileBaseDir = base; } xstrscat(&msg->text, "+", areatag, "\r", NULL); } else { xscatprintf(&(msg->text), "-%s\r", areatag); } return 0; } static int compare_links_priority(const void *a, const void *b) { int ia = *((int*)a); int ib = *((int*)b); if(config->links[ia].forwardFilePriority < config->links[ib].forwardFilePriority) return -1; else if(config->links[ia].forwardFilePriority > config->links[ib].forwardFilePriority) return 1; else return 0; } int forwardRequest(char *areatag, s_link *dwlink) { unsigned int i, rc = 1; s_link *uplink; int *Indexes; unsigned int Requestable = 0; /* From Lev Serebryakov -- sort Links by priority */ Indexes = smalloc(sizeof(int)*config->linkCount); for (i = 0; i < config->linkCount; i++) { if (config->links[i].forwardFileRequests) Indexes[Requestable++] = i; } qsort(Indexes,Requestable,sizeof(Indexes[0]),compare_links_priority); for (i = 0; i < Requestable; i++) { uplink = &(config->links[Indexes[i]]); if (uplink->forwardFileRequests && (uplink->LinkGrp) ? grpInArray(uplink->LinkGrp,dwlink->AccessGrp,dwlink->numAccessGrp) : 1) { char *descr = NULL; if (uplink->forwardFileRequestFile!=NULL) { // first try to find the areatag in forwardRequestFile if (IsAreaAvailable(areatag,uplink->forwardFileRequestFile,&descr,1)) { forwardRequestToLink(areatag,descr,uplink,dwlink,0); rc = 0; } else { rc = 2; }// found link with freqfile, but there is no areatag nfree(descr); } else { forwardRequestToLink(areatag,descr,uplink,dwlink,0); rc = 0; }//(uplink->forwardRequestFile!=NULL) if (rc==0) { nfree(Indexes); return rc; } } // if (uplink->forwardFileRequests && (uplink->LinkGrp) ? } // for (i = 0; i < Requestable; i++) { // link with "forwardFileRequests on" not found nfree(Indexes); return rc; } char *subscribe(s_link *link, s_message *msg, char *cmd) { unsigned int i, c, rc=4,found=0; char *line, *report = NULL; s_filearea *area; line = cmd; if (line[0]=='+') line++; report=(char*)scalloc(1, sizeof(char)); for (i=0; ifileAreaCount; i++) { rc=subscribeAreaCheck(&(config->fileAreas[i]),msg,line, link); if (rc == 4) continue; area = &(config->fileAreas[i]); for (c = 0; cdownlinkCount; c++) { if (link == area->downlinks[c]->link) { if (area->downlinks[c]->mandatory) rc=5; break; } } found = 1; switch (rc) { case 0: xscatprintf(&report, "%s Already linked\r", area->areaName); w_log( LL_AREAFIX, "FileFix: %s already linked to %s", aka2str(link->hisAka), area->areaName); break; case 1: case 3: changeconfig (getConfigFileName(), area, link, 0); addlink(link, area); xscatprintf(&report, "%s Added\r",area->areaName); w_log( LL_AREAFIX, "FileFix: %s subscribed to %s",aka2str(link->hisAka),area->areaName); break; case 5: xscatprintf(&report, "%s Link is not possible\r", area->areaName); w_log( LL_AREAFIX, "FileFix: area %s -- link is not possible for %s", area->areaName, aka2str(link->hisAka)); break; default : xscatprintf(&report, "%s No access\r", area->areaName); w_log( LL_AREAFIX, "FileFix: filearea %s -- no access for %s", area->areaName, aka2str(link->hisAka)); continue; } } if(rc == 4 && link->denyFRA==0 && !found) { // try to forward request if ((rc=forwardRequest(line, link))==2) { xscatprintf(&report, "%s no uplinks to forward\r", line); w_log( LL_AREAFIX, "Filefix: %s - no uplinks to forward", line); } else if (rc==0) { xscatprintf(&report, "%s request forwarded\r", line); w_log( LL_AREAFIX, "Filefix: %s - request forwarded", line); } } if (*report == '\0') { xscatprintf(&report,"%s Not found\r",line); w_log( LL_AREAFIX, "FileFix: filearea %s is not found",line); } return report; } char *unsubscribe(s_link *link, s_message *msg, char *cmd) { unsigned int i, c, rc = 2; char *line; char *report=NULL; s_filearea *area; line = cmd; if (line[1]=='-') return NULL; line++; for (i = 0; i< config->fileAreaCount; i++) { rc=subscribeAreaCheck(&(config->fileAreas[i]),msg,line, link); if ( rc==4 ) continue; area = &(config->fileAreas[i]); for (c = 0; cdownlinkCount; c++) { if (link == area->downlinks[c]->link) { if (area->downlinks[c]->mandatory) rc=5; break; } } switch (rc) { case 0: removelink(link, area); changeconfig (getConfigFileName(), area, link, 1); xscatprintf(&report, "%s Unlinked\r",area->areaName); w_log( '8', "FileFix: %s unlinked from %s",aka2str(link->hisAka),area->areaName); break; case 1: if (strstr(line, "*")) continue; xscatprintf(&report, "%s Not linked\r",line); w_log( '8', "FileFix: area %s is not linked to %s", area->areaName, aka2str(link->hisAka)); break; case 5: xscatprintf(&report, "%s Unlink is not possible\r", area->areaName); w_log( '8', "FileFix: area %s -- unlink is not possible for %s", area->areaName, aka2str(link->hisAka)); break; default: w_log( '8', "FileFix: area %s -- no access for %s", area->areaName, aka2str(link->hisAka)); continue; } } if (!report) { xscatprintf(&report, "%s Not found\r",line); w_log( '8', "FileFix: area %s is not found", line); } return report; } char *resend(s_link *link, s_message *msg, char *cmd) { unsigned int rc, i; char *line; char *report=NULL, *token = NULL, *filename=NULL, *filearea=NULL; s_filearea *area = NULL; line = cmd; line=stripLeadingChars(line, " \t"); token = strtok(line, " \t\0"); if (token == NULL) { xscatprintf(&report, "Error in line! Format: %%Resend \r"); return report; } filename = sstrdup(token); token=stripLeadingChars(strtok(NULL, "\0"), " "); if (token == NULL) { nfree(filename); xscatprintf(&report, "Error in line! Format: %%Resend \r"); return report; } filearea = sstrdup(token); area = getFileArea(config,filearea); if (area != NULL) { rc = 1; for (i = 0; idownlinkCount;i++) if (addrComp(msg->origAddr, area->downlinks[i]->link->hisAka)==0) rc = 0; if (rc == 1 && area->mandatory == 1) rc = 5; else rc = send(filename,filearea,aka2str(link->hisAka)); switch (rc) { case 0: xscatprintf(&report, "Send %s from %s for %s\r", filename,filearea,aka2str(link->hisAka)); break; case 1: xscatprintf(&report, "Error: Passthrough filearea %s!\r",filearea); w_log( '8', "FileFix %%Resend: Passthrough filearea %s", filearea); break; case 2: xscatprintf(&report, "Error: Filearea %s not found!\r",filearea); w_log( '8', "FileFix %%Resend: Filearea %s not found", filearea); break; case 3: xscatprintf(&report, "Error: File %s not found!\r",filename); w_log( '8', "FileFix %%Resend: File %s not found", filename); break; case 5: xscatprintf(&report, "Error: You don't have access for filearea %s!\r",filearea); w_log( '8', "FileFix %%Resend: Link don't have access for filearea %s", filearea); break; } } else { xscatprintf(&report, "Error: filearea %s not found!\r",filearea); w_log( '8', "FileFix %%Resend: Filearea %s not found", filearea); } nfree(filearea); nfree(filename); return report; } char *pause_link(s_message *msg, s_link *link) { char *tmp = NULL; char *report=NULL; if ((link->Pause & FPAUSE) != FPAUSE) { if (Changepause(getConfigFileName(), link,0,FPAUSE) == 0) return NULL; } xstrcat(&report, " System switched to passive\r"); tmp = linked (msg, link, 0); xstrcat(&report, tmp); nfree(tmp); return report; } char *resume_link(s_message *msg, s_link *link) { char *tmp = NULL, *report=NULL; if ((link->Pause & FPAUSE) == FPAUSE) { if (Changepause(getConfigFileName(), link,0,FPAUSE) == 0) return NULL; } xstrcat(&report, " System switched to active\r"); tmp = linked(msg, link, 0); xstrcat(&report, tmp); nfree(tmp); return report; } int tellcmd(char *cmd) { char *line = NULL; if (strncasecmp(cmd, "* Origin:", 9) == 0) return NOTHING; line = strpbrk(cmd, " \t"); if (line && *cmd != '%') *line = 0; line = cmd; switch (line[0]) { case '%': line++; if (*line == 0) return ERROR; if (stricmp(line,"list")==0) return LIST; if (stricmp(line,"help")==0) return HELP; if (stricmp(line,"unlinked")==0) return UNLINK; if (stricmp(line,"linked")==0) return LINKED; if (stricmp(line,"avail")==0) return AVAIL; if (stricmp(line,"query")==0) return LINKED; if (stricmp(line,"pause")==0) return PAUSE; if (stricmp(line,"resume")==0) return RESUME; if (stricmp(line,"info")==0) return INFO; if (strncasecmp(line, "resend", 6)==0) if (line[6] != 0) return RESEND; return ERROR; case '\001': return NOTHING; case '\000': return NOTHING; case '-' : return DEL; case '+': line++; if (line[0]=='\000') return ERROR; default: return ADD; } return 0; } char *processcmd(s_link *link, s_message *msg, char *line, int cmd) { char *report = NULL; switch (cmd) { case NOTHING: return NULL; case LIST: report = list (msg, link); RetFix=LIST; break; case HELP: report = help (link); RetFix=HELP; break; case ADD: report = subscribe (link,msg,line); RetFix=ADD; break; case DEL: report = unsubscribe (link,msg,line); RetFix=DEL; break; case UNLINK: report = unlinked (msg, link); RetFix=UNLINK; break; case LINKED: report = linked (msg, link, 1); RetFix=LINKED; break; case AVAIL: report = available (link); RetFix=AVAIL; break; case PAUSE: report = pause_link (msg, link); RetFix=PAUSE; break; case RESUME: report = resume_link (msg, link); RetFix=RESUME; break; /* case INFO: report = info_link(msg, link); RetFix=INFO; break;*/ case RESEND: report = resend(link, msg, line+7); RetFix=RESEND; break; case ERROR: report = errorRQ(line); RetFix=ERROR; break; default: return NULL; } return report; } char *areastatus(char *preport, char *text) { char *pth = NULL, *ptmp = NULL, *tmp = NULL, *report = NULL, tmpBuff[256]; pth = (char*)scalloc(1, sizeof(char)); tmp = preport; ptmp = strchr(tmp, '\r'); while (ptmp) { *ptmp=0; ptmp++; report=strchr(tmp, ' '); *report=0; report++; if (strlen(tmp) > 50) tmp[50] = 0; if (50-strlen(tmp) == 0) sprintf(tmpBuff, " %s %s\r", tmp, report); else if (50-strlen(tmp) == 1) sprintf(tmpBuff, " %s %s\r", tmp, report); else sprintf(tmpBuff, " %s %s %s\r", tmp, print_ch(50-strlen(tmp)-1, '.'), report); pth=(char*)srealloc(pth, strlen(tmpBuff)+strlen(pth)+1); strcat(pth, tmpBuff); tmp=ptmp; ptmp = strchr(tmp, '\r'); } tmp = (char*)scalloc(strlen(pth)+strlen(text)+1, sizeof(char)); strcpy(tmp, text); strcat(tmp, pth); free(text); free(pth); return tmp; } void preprocText(char *preport, s_message *msg) { msg->text = createKludges(config->disableTID, NULL, &msg->origAddr, &msg->destAddr, versionStr); xstrcat(&msg->text, "\001FLAGS NPD\r"); xstrcat(&msg->text, preport); xscatprintf(&msg->text, " \r--- %s FileFix\r", versionStr); msg->textLength=(int)strlen(msg->text); } char *textHead(void) { char *text_head=NULL; xscatprintf(&text_head, " FileArea%sStatus\r", print_ch(44,' ')); xscatprintf(&text_head, " %s -------------------------\r",print_ch(50, '-')); return text_head; } void RetMsg(s_message *msg, s_link *link, char *report, char *subj) { s_message *tmpmsg; tmpmsg = makeMessage(link->ourAka, &(link->hisAka), msg->toUserName, msg->fromUserName, subj, 1,config->filefixKillReports); preprocText(report, tmpmsg); writeNetmail(tmpmsg, config->robotsArea); freeMsgBuffers(tmpmsg); free(tmpmsg); } void sendFilefixMessages() { s_link *link = NULL; s_message *linkmsg; unsigned int i; for (i = 0; i < config->linkCount; i++) { if (config->links[i].msg == NULL) continue; link = &(config->links[i]); linkmsg = link->msg; xscatprintf(&(linkmsg->text), " \r--- %s Filefix\r", versionStr); linkmsg->textLength = strlen(linkmsg->text); w_log(LL_AREAFIX, "Filefix: write netmail msg for %s", aka2str(link->hisAka)); writeNetmail(linkmsg, config->robotsArea); freeMsgBuffers(linkmsg); nfree(linkmsg); link->msg = NULL; } } //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- int processFileFix(s_message *msg) { int security=1, notforme = 0; s_link *link = NULL; s_link *tmplink = NULL; char *textBuff = NULL, *report=NULL, *preport = NULL, *token = NULL; // find link link=getLinkFromAddr(config, msg->origAddr); // this is for me? if (link!=NULL) notforme=addrComp(msg->destAddr, *link->ourAka); // ignore msg for other link (maybe this is transit...) if (notforme) { return 2; } // security ckeck. link,araefixing & password. if (link != NULL) { if (link->FileFix==1) { if (link->fileFixPwd!=NULL) { if (stricmp(link->fileFixPwd,msg->subjectLine)==0) security=0; else security=3; } } else security=2; } else security=1; if (!security) { textBuff = msg->text; token = strseparate (&textBuff, "\n\r"); while(token != NULL) { preport = processcmd( link, msg, stripLeadingChars(token, " \t"), tellcmd (token) ); if (preport != NULL) { switch (RetFix) { case LIST: RetMsg(msg, link, preport, "FileFix reply: list request"); break; case HELP: RetMsg(msg, link, preport, "FileFix reply: help request"); break; case ADD: case DEL: if (report == NULL) report = textHead(); report = areastatus(preport, report); break; case UNLINK: RetMsg(msg, link, preport, "FileFix reply: unlinked request"); break; case LINKED: RetMsg(msg, link, preport, "FileFix reply: linked request"); w_log( '8', "FileFix: linked fileareas list sent to %s", aka2str(link->hisAka)); break; case AVAIL: RetMsg(msg, link, preport, "FileFix reply: avail request"); break; case PAUSE: case RESUME: RetMsg(msg, link, preport, "FileFix reply: node change request"); break; case INFO: RetMsg(msg, link, preport, "FileFix reply: link information"); break; case RESEND: RetMsg(msg, link, preport, "FileFix reply: resend request"); break; case ERROR: if (report == NULL) report = textHead(); report = areastatus(preport, report); break; default: break; } free(preport); } token = strseparate (&textBuff, "\n\r"); } } else { if (link == NULL) { tmplink = (s_link*)scalloc(1, sizeof(s_link)); tmplink->ourAka = &(msg->destAddr); tmplink->hisAka.zone = msg->origAddr.zone; tmplink->hisAka.net = msg->origAddr.net; tmplink->hisAka.node = msg->origAddr.node; tmplink->hisAka.point = msg->origAddr.point; link = tmplink; } // security problem switch (security) { case 1: report = sstrdup(" \r your system is unknown\r"); break; case 2: report = sstrdup(" \r filefix is turned off\r"); break; case 3: report = sstrdup(" \r password error\r"); break; default: report = sstrdup(" \r unknown error. mail to sysop.\r"); break; } RetMsg(msg, link, report, "security violation"); free(report); w_log( '8', "FileFix: security violation from %s", aka2str(link->hisAka)); free(tmplink); return 0; } if ( report != NULL ) { preport=linked(msg, link, 0); xstrcat(&report, preport); free(preport); RetMsg(msg, link, report, "node change request"); free(report); } w_log( '8', "FileFix: sucessfully done for %s",aka2str(link->hisAka)); // send msg to the links (forward requests to areafix) sendFilefixMessages(); return 1; } void ffix(s_addr addr, char *cmd) { s_link *link = NULL; s_message *tmpmsg = NULL; if (cmd) { link = getLinkFromAddr(config, addr); if (link) { tmpmsg = makeMessage(&addr, link->ourAka, link->name, link->RemoteRobotName ? link->RemoteRobotName : "Filefix", link->fileFixPwd ? link->fileFixPwd : "", 1, config->areafixKillReports); tmpmsg->text = cmd; processFileFix(tmpmsg); tmpmsg->text=NULL; freeMsgBuffers(tmpmsg); } else w_log(LL_ERR, "FileFix: no such link in config: %s!", aka2str(addr)); } else scan(); } /* file echo autocreation */ int autoCreate(char *c_area, char *descr, s_addr* pktOrigAddr, s_addr* dwLink) { FILE *f; char *NewAutoCreate = NULL; char *fileName = NULL; char *bDir = NULL; char *fileechoFileName = NULL; char *buff= NULL, hisaddr[20]; s_link *creatingLink; s_message *msg; s_filearea *area; FILE *echotosslog; creatingLink = getLinkFromAddr(config, *pktOrigAddr); fileechoFileName = makeMsgbFileName(config, c_area); // translating name of the area to lowercase/uppercase if (config->createAreasCase == eUpper) strUpper(c_area); else strLower(c_area); // translating filename of the area to lowercase/uppercase if (config->areasFileNameCase == eUpper) strUpper(fileechoFileName); else strLower(fileechoFileName); bDir = (creatingLink->fileBaseDir) ? creatingLink->fileBaseDir : config->fileAreaBaseDir; if (creatingLink->autoFileCreateSubdirs && strcasecmp(bDir,"passthrough")) { if (creatingLink->autoFileCreateSubdirs) { char *cp; for (cp = fileechoFileName; *cp; cp++) { if (*cp == '.') { *cp = PATH_DELIM; } } } xscatprintf(&buff,"%s%s",bDir,fileechoFileName); if (_createDirectoryTree(buff)) { if (!quiet) fprintf(stderr, "cannot make all subdirectories for %s\n", fileechoFileName); nfree(buff); return 1; } nfree(buff); } fileName = creatingLink->autoFileCreateFile; if (fileName == NULL) fileName = getConfigFileName(); f = fopen(fileName, "a"); if (f == NULL) { f = fopen(getConfigFileName(), "a"); if (f == NULL) { if (!quiet) fprintf(stderr,"autocreate: cannot open config file\n"); return 1; } } /* making address of uplink */ strcpy(hisaddr,aka2str(*pktOrigAddr)); /* write new line in config file */ xscatprintf(&buff, "FileArea %s %s%s -a %s ", c_area, bDir, (strcasecmp(bDir,"passthrough") == 0) ? "" : fileechoFileName, aka2str(*(creatingLink->ourAka)) ); if ( creatingLink->LinkGrp && !(creatingLink->autoFileCreateDefaults && (hpt_stristr(creatingLink->autoFileCreateDefaults, "-g ")!=NULL)) ) { xscatprintf(&buff,"-g %s ",creatingLink->LinkGrp); } if (creatingLink->autoFileCreateDefaults) { NewAutoCreate = sstrdup(creatingLink->autoFileCreateDefaults); if ((fileName=strstr(NewAutoCreate,"-d ")) !=NULL ) { if (descr) { *fileName = '\0'; xscatprintf(&buff,"%s -d \"%s\"",NewAutoCreate,descr); } else { xstrcat(&buff, NewAutoCreate); } } else if (descr) { xscatprintf(&buff,"%s -d \"%s\"",NewAutoCreate,descr); } nfree(NewAutoCreate); } else if (descr) { xscatprintf(&buff,"-d \"%s\"",descr); } xscatprintf(&buff," %s",hisaddr); if(dwLink) xscatprintf(&buff," %s",aka2str(*dwLink)); if( fseek (f, -2L, SEEK_END) == 0) { char CR; CR = getc (f); /* may be it is CR aka '\r' */ if (getc(f) != '\n') { fseek (f, 0L, SEEK_END); /* not neccesary, but looks better ;) */ fputs (cfgEol(), f); } else { fseek (f, 0L, SEEK_END); } /* correct EOL in memory */ if(CR == '\r') xstrcat(&buff,"\r\n"); /* DOS EOL */ else xstrcat(&buff,"\n"); /* UNIX EOL */ } else { xstrcat(&buff,(char*)cfgEol()); /* config depended EOL */ } fprintf(f, "%s", buff); fclose(f); /* add new created echo to config in memory */ parseLine(buff,config); w_log( '8', "FileArea '%s' autocreated by %s", c_area, hisaddr); /* report about new filearea */ if (config->ReportTo && !cmAnnNewFileecho && (area = getFileArea(config, c_area)) != NULL) { if (getNetMailArea(config, config->ReportTo) != NULL) { msg = makeMessage(area->useAka, area->useAka, versionStr, config->sysop, "Created new fileareas", 1, config->filefixKillReports); msg->text = createKludges(config->disableTID,NULL, area->useAka,area->useAka,versionStr); } else { msg = makeMessage(area->useAka, area->useAka, versionStr, "All", "Created new fileareas", 0, config->filefixKillReports); msg->text = createKludges(config->disableTID,config->ReportTo, area->useAka, area->useAka,versionStr); } /* endif */ xstrcat(&msg->text, "\001FLAGS NPD\r"); sprintf(buff, "\r \rNew filearea: %s\r\rDescription : %s\r", area->areaName, (area->description) ? area->description : ""); msg->text = (char*)srealloc(msg->text, strlen(msg->text)+strlen(buff)+1); strcat(msg->text, buff); writeMsgToSysop(msg, config->ReportTo); freeMsgBuffers(msg); nfree(msg); if (config->echotosslog != NULL) { echotosslog = fopen (config->echotosslog, "a"); fprintf(echotosslog,"%s\n",config->ReportTo); fclose(echotosslog); } } else { } /* endif */ if (cmAnnNewFileecho) announceNewFileecho (announcenewfileecho, c_area, hisaddr); return 0; }