4898794edd81be5285ea6e544acbedeaeb31bf78 max Tue Nov 23 08:10:57 2021 -0800 Fixing pointers to README file for license in all source code files. refs #27614 diff --git src/hg/hgUserSuggestion/hgUserSuggestion.c src/hg/hgUserSuggestion/hgUserSuggestion.c index 2b99f04..77c5f50 100644 --- src/hg/hgUserSuggestion/hgUserSuggestion.c +++ src/hg/hgUserSuggestion/hgUserSuggestion.c @@ -1,519 +1,519 @@ /* hgUserSuggestion - CGI-script to collect user's suggestion. */ /* Copyright (C) 2013 The Regents of the University of California - * See README in this or parent directory for licensing information. */ + * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */ #include "common.h" #include "errAbort.h" #include "hCommon.h" #include "jksql.h" #include "portable.h" #include "cheapcgi.h" #include "htmshell.h" #include "hdb.h" #include "hui.h" #include "cart.h" #include "hPrint.h" #include "dbDb.h" #include "web.h" #include "hash.h" #include "hgConfig.h" #include "hgUserSuggestion.h" #include "mailViaPipe.h" /* ---- Global variables. ---- */ struct cart *cart; /* The user's ui state. */ struct hash *oldVars = NULL; /* ---- Global helper functions ---- */ void checkHgConfForSuggestion() /* Abort if hg.conf has not been set up to accept suggestion */ { if (isEmpty(cfgOption(CFG_SUGGEST_MAILTOADDR)) || isEmpty(cfgOption(CFG_SUGGEST_MAILFROMADDR)) || isEmpty(cfgOption(CFG_FILTERKEYWORD)) || isEmpty(cfgOption(CFG_SUGGEST_MAIL_SIGNATURE)) || isEmpty(cfgOption(CFG_SUGGEST_MAIL_RETURN_ADDR)) || isEmpty(cfgOption(CFG_SUGGEST_BROWSER_NAME))) errAbort("This Genome Browser has not been configured to accept suggestions yet. Please contact the browser administrator for more information."); } char *mailToAddr() /* Return the address to send suggestion to */ { return cloneString(cfgOption(CFG_SUGGEST_MAILTOADDR)); } char *mailFromAddr() /* Return the bogus sender address to help filter out spam */ { return cloneString(cfgOption(CFG_SUGGEST_MAILFROMADDR)); } char *filterKeyword() /* Return the keyword used to filter out spam */ { return cloneString(cfgOption(CFG_FILTERKEYWORD)); } char *mailSignature() /* Return the signature to be used by outbound mail. */ { return cloneString(cfgOption(CFG_SUGGEST_MAIL_SIGNATURE)); } char *mailReturnAddr() /* Return the return addr. to be used by outbound mail. */ { return cloneString(cfgOption(CFG_SUGGEST_MAIL_RETURN_ADDR)); } char *browserName() /* Return the browser name like 'UCSC Genome Browser' */ { return cloneString(cfgOption(CFG_SUGGEST_BROWSER_NAME)); } static char *now() /* Return a mysql-formatted time like "2008-05-19 15:33:34". */ { char nowBuf[512]; time_t curtime; curtime = time (NULL); struct tm *theTime = localtime(&curtime); strftime(nowBuf, sizeof nowBuf, "%Y-%m-%d %H:%M:%S", theTime); return cloneString(nowBuf); } int spc_email_isvalid(const char *address) { /* Check the format of an email address syntactically. Return 1 if * valid, else 0 */ /* Code copied from the book: "Secure Programming Cookbook for C and C++" By: John Viega; Matt Messier Publisher: O'Reilly Media, Inc. Pub. Date: July 14, 2003 Print ISBN-13: 978-0-596-00394-4 */ int count = 0; const char *c, *domain; static char *rfc822_specials = "()<>@,;:\\\"[]"; /* first we validate the name portion (name@domain) */ for (c = address; *c; c++) { if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) == '\"')) { while (*++c) { if (*c == '\"') break; if (*c == '\\' && (*++c == ' ')) continue; if (*c <= ' ' || *c >= 127) return 0; } if (!*c++) return 0; if (*c == '@') break; if (*c != '.') return 0; continue; } if (*c == '@') break; if (*c <= ' ' || *c >= 127) return 0; if (strchr(rfc822_specials, *c)) return 0; } if (c == address || *(c - 1) == '.') return 0; /* next we validate the domain portion (name@domain) */ if (!*(domain = ++c)) return 0; do { if (*c == '.') { if (c == domain || *(c - 1) == '.') return 0; count++; } if (*c <= ' ' || *c >= 127) return 0; if (strchr(rfc822_specials, *c)) return 0; } while (*++c); return (count >= 1); } boolean validateCategory(char *category) /* Validate the Category from the request */ { const char *cat[5] = {"Tracks", "Genome Assemblies", "Browser Tools", "Command-line Utilities", "Others"}; int i; for(i=0;i<5;i++) { if (strcmp(cat[i], category)==0) return TRUE; } return FALSE; } /* javascript functions */ void printMainForm() /* Create the main suggestion form */ { hPrintf( "
\n\n"); jsOnEventById("click","sendButton","submitform();"); } void printValidateScript() /* javascript to validate form inputs */ { jsInline( " function validateMainForm(theform)\n" " {\n" " var x=theform.suggestName.value;\n" " if (x==null || x==\"\")\n" " {\n" " alert(\"Name field must be filled out\");\n" " theform.suggestName.focus() ;\n" " return false;\n" " }\n" " var y=theform.suggestEmail.value;\n" " if (y==null || y==\"\")\n" " {\n" " alert(\"Email field must be filled out\");\n" " theform.suggestEmail.focus() ;\n" " return false;\n" " }\n" " if (!validateMailAddr(theform.suggestEmail.value))\n" " {\n" " alert(\"Not a valid e-mail address\");\n" " theform.suggestEmail.focus() ;\n" " return false;\n" " }\n" " var str1 = theform.suggestEmail.value;\n" " var str2 = theform.suggestCfmEmail.value;\n" " if (str2==null || str2==\"\")\n" " {\n" " alert(\"Please re-enter your email address.\");\n" " theform.suggestCfmEmail.focus();\n" " return false;\n" " }\n" " if (str1 != str2)\n" " {\n" " alert(\"Email addresses do not match, please re-enter.\");\n" " theform.suggestCfmEmail.focus();\n" " return false;\n" " }\n" " var y=theform.suggestSummary.value;\n" " if (y==null || y==\"\")\n" " {\n" " alert(\"Summary field must be filled out\");\n" " theform.suggestSummary.focus() ;\n" " return false;\n" " } \n" " return true; \n" " }" " function validateMailAddr(x)\n" " {\n" " var atpos=x.indexOf(\"@\");\n" " var dotpos=x.lastIndexOf(\".\");\n" " if (atpos<1 || dotpos"
"You may follow up on the status of your request at any time by "
"contacting us and quoting your reference number:
%s
"
"A copy of this information has also been sent to you at %s.
Click here if you wish to make additional suggestions.
"); hPrintf( ""
"Your suggestion summary:
"
"%s
"
"Your suggestion details:
"
"
%s" "", summary, details); } void printInvalidForm() /* display invalid form page */ { hPrintf( "
" "The form is invalid. Please correct it and " "submit again.
" ); jsOnEventById("click", "goBack", "history.go(-1)"); } void printInvalidCategory(char *invalidCategory) /* display invalid category page */ { hPrintf( "" "The category \"%s\" is invalid. Please correct it and " "submit again.
", invalidCategory); jsOnEventById("click", "goBack", "history.go(-1)"); } void printInvalidEmailAddr(char *invalidEmailAddr) /* display suggestion confirm page */ { hPrintf( "" "The email address \"%s\" is invalid. Please correct it and " "submit again.
", invalidEmailAddr); jsOnEventById("click", "goBack", "history.go(-1)"); } void sendSuggestionBack(char *sName, char *sEmail, char *sCategory, char *sSummary, char *sDetails, char *suggestID) /* send back the suggestion */ { /* parameters from hg.cong */ char *mailTo = mailToAddr(); char *mailFrom=mailFromAddr(); char *filter=filterKeyword(); char subject[512]; char msg[4608]; /* need to make larger */ safef(msg, sizeof(msg), "SuggestionID:: %s\nUserName:: %s\nUserEmail:: %s\nCategory:: %s\nSummary:: %s\n\n\nDetails::\n%s", suggestID, sName, sEmail, sCategory, sSummary, sDetails); safef(subject, sizeof(subject),"%s %s", filter, suggestID); // ignore returned result mailViaPipe(mailTo, subject, msg, mailFrom); } void sendConfirmMail(char *emailAddr, char *suggestID, char *summary, char *details) /* send user suggestion confirm mail */ { char subject[512]; char msg[4608]; char *remoteAddr=getenv("REMOTE_ADDR"); char brwName[512]; char returnAddr[512]; char signature[512]; char userEmailAddr[512]; safecpy(brwName,sizeof(brwName), browserName()); safecpy(returnAddr,sizeof(returnAddr), mailReturnAddr()); safecpy(signature,sizeof(signature), mailSignature()); safecpy(userEmailAddr, sizeof(userEmailAddr),emailAddr); safef(subject, sizeof(subject),"Thank you for your suggestion to the %s", brwName); safef(msg, sizeof(msg), " Someone (probably you, from IP address %s) submitted a suggestion to the %s regarding \"%s\".\n\n The suggestion has been assigned a reference number of \"%s\". If you wish to follow up on the progress of this suggestion with browser staff, you may contact us at %s. Please include the reference number of your suggestion in the email.\n\nThank you for your input,\n%s\n\nYour suggestion summary:\n%s\n\nYour suggestion details:\n%s", remoteAddr, brwName, summary, suggestID, returnAddr, signature, summary, details); // ignore returned result mailViaPipe(userEmailAddr, subject, msg, returnAddr); } void askForSuggest(char *organism, char *db) /* Put up the suggestion form. */ { printMainForm(); printValidateScript(); printCheckCaptchaScript(); printSubmitFormScript(); //cartSaveSession(cart); } void submitSuggestion() /* send the suggestion to ,.. */ { /* parameters from hg.cong */ char *filter=filterKeyword(); /* values from cart */ char *sName=cartUsualString(cart,"suggestName",""); char *sEmail=cartUsualString(cart,"suggestEmail",""); char *sCategory=cartUsualString(cart,"suggestCategory",""); char *sSummary=cartUsualString(cart,"suggestSummary",""); char *sDetails=cartUsualString(cart,"suggestDetails",""); char *sWebsite=cartUsualString(cart,"suggestWebsite",""); char suggestID[512]; safef(suggestID, sizeof(suggestID),"%s %s", sEmail, now()); char subject[512]; safef(subject, sizeof(subject),"%s %s", filter, suggestID); /* reject if the hidden field is not blank */ if (isNotEmpty(sWebsite)) { printInvalidForm(); cartSetString(cart, "suggestWebsite", ""); return; } /* reject suggestion if category is invalid */ if (!validateCategory(sCategory)) { printInvalidCategory(sCategory); return; } /* Send back suggestion only with valid user email address */ if (spc_email_isvalid(sEmail) != 0) { /* send back the suggestion */ sendSuggestionBack(sName, sEmail, sCategory, sSummary, sDetails, suggestID); /* send confirmation mail to user */ sendConfirmMail(sEmail,suggestID, sSummary, sDetails); /* display confirmation page */ printSuggestionConfirmed(sSummary, suggestID, sEmail, mailReturnAddr(), sDetails); } else { /* save all field value in cart */ printInvalidEmailAddr(sEmail); } cartRemove(cart, "do.suggestSendMail"); } void doMiddle(struct cart *theCart) /* Write header and body of html page. */ { char *db, *organism; cart = theCart; getDbAndGenome(cart, &db, &organism, oldVars); cartWebStart(theCart, db, "UCSC Genome Browser: Suggestion Box"); checkHgConfForSuggestion(); if (cartVarExists(cart, "do.suggestSendMail")) { submitSuggestion(); cartRemove(cart, "do.suggestSendMail"); return; } askForSuggest(organism,db); cartWebEnd(); } /* Null terminated list of CGI Variables we don't want to save * permanently. */ char *excludeVars[] = {"Submit", "submit", "Clear", NULL}; int main(int argc, char *argv[]) /* Process command line. */ { long enteredMainTime = clock1000(); oldVars = hashNew(10); cgiSpoof(&argc, argv); cartEmptyShell(doMiddle, hUserCookie(), excludeVars, oldVars); cgiExitTime("hgUserSuggestion", enteredMainTime); return 0; }