static void read_blacklist(TSCont contp) { char blacklist_file[1024]; TSFile file; sprintf(blacklist_file, "%s/blacklist.txt", TSPluginDirGet()); file = TSfopen(blacklist_file, "r"); nsites = 0; /* If the Mutext lock is not successful try again in RETRY_TIME */ if (TSMutexLockTry(sites_mutex) != TS_SUCCESS) { if (file != NULL) { TSfclose(file); } TSContSchedule(contp, RETRY_TIME, TS_THREAD_POOL_DEFAULT); return; } if (file != NULL) { char buffer[1024]; while (TSfgets(file, buffer, sizeof(buffer) - 1) != NULL && nsites < MAX_NSITES) { char *eol; if ((eol = strstr(buffer, "\r\n")) != NULL) { /* To handle newlines on Windows */ *eol = '\0'; } else if ((eol = strchr(buffer, '\n')) != NULL) { *eol = '\0'; } else { /* Not a valid line, skip it */ continue; } if (sites[nsites] != NULL) { TSfree(sites[nsites]); } sites[nsites] = TSstrdup(buffer); nsites++; } TSfclose(file); } else { TSError("[%s] Unable to open %s", PLUGIN_NAME, blacklist_file); TSError("[%s] All sites will be allowed", PLUGIN_NAME); } TSMutexUnlock(sites_mutex); }
void TSPluginInit(int argc, const char *argv[]) { TSFile filep; char buf[4096]; int i; TSPluginRegistrationInfo info; info.plugin_name = "file_plugin"; info.vendor_name = "MyCompany"; info.support_email = "*****@*****.**"; if (TSPluginRegister(TS_SDK_VERSION_3_0, &info) != TS_SUCCESS) { TSError("Plugin registration failed.\n"); } if (!check_ts_version()) { TSError("Plugin requires Traffic Server 3.0 or later\n"); return; } for (i = 1; i < argc; i++) { filep = TSfopen(argv[i], "r"); if (!filep) { continue; } while (TSfgets(filep, buf, 4096)) { TSDebug("debug-file", "%s", buf); } TSfclose(filep); } }
void TSPluginInit(int argc, const char *argv[]) { TSFile filep; char buf[4096]; int i; TSPluginRegistrationInfo info; info.plugin_name = "file_plugin"; info.vendor_name = "MyCompany"; info.support_email = "*****@*****.**"; if (TSPluginRegister(&info) != TS_SUCCESS) { TSError("[file-1] Plugin registration failed."); } for (i = 1; i < argc; i++) { filep = TSfopen(argv[i], "r"); if (!filep) { continue; } while (TSfgets(filep, buf, 4096)) { TSDebug("debug-file", "%s", buf); } TSfclose(filep); } }
static void load_config_file(config_holder_t *config_holder) { TSFile fh; struct stat s; config_t *newconfig, *oldconfig; TSCont free_cont; configReloadRequests++; lastReloadRequest = time(NULL); // check date if (stat(config_holder->config_path, &s) < 0) { TSDebug(PLUGIN_TAG, "Could not stat %s", config_holder->config_path); if(config_holder->config) { return; } } else { TSDebug(PLUGIN_TAG, "s.st_mtime=%lu, last_load=%lu", s.st_mtime, config_holder->last_load); if (s.st_mtime < config_holder->last_load) { return; } } TSDebug(PLUGIN_TAG, "Opening config file: %s", config_holder->config_path); fh = TSfopen(config_holder->config_path, "r"); if (!fh) { TSError("[%s] Unable to open config: %s.\n", PLUGIN_TAG, config_holder->config_path); if(config_holder->config) { return; } } newconfig = 0; newconfig = new_config(fh); if(newconfig) { configReloads++; lastReload = lastReloadRequest; config_holder->last_load = lastReloadRequest; config_t ** confp = &(config_holder->config); oldconfig = __sync_lock_test_and_set(confp, newconfig); if (oldconfig) { TSDebug(PLUGIN_TAG, "scheduling free: %p (%p)", oldconfig, newconfig); free_cont = TSContCreate(free_handler, NULL); TSContDataSet(free_cont, (void *) oldconfig); TSContSchedule(free_cont, FREE_TMOUT, TS_THREAD_POOL_TASK); } } if(fh) TSfclose(fh); return; }
static char * getFile(char *filename, char *buffer, int bufferSize) { TSFile f= 0; size_t s = 0; f = TSfopen(filename, "r"); if (!f) { buffer[0] = 0; return buffer; } s = TSfread(f, buffer, bufferSize); if (s > 0) buffer[s] = 0; else buffer[0] = 0; TSfclose(f); return buffer; }
/*------------------------------------------------------------------------- psi_include Read file to include. Copy its content into an iobuffer. This is the function doing blocking calls and called by the plugin's threads Input: data continuation for the current transaction Output : data->psi_buffer contains the file content data->psi_sucess 0 if include failed, 1 if success Return Value: 0 if failure 1 if success -------------------------------------------------------------------------*/ static int psi_include(TSCont contp, void *edata) { #define BUFFER_SIZE 1024 ContData *data; TSFile filep; char buf[BUFFER_SIZE]; char inc_file[PSI_PATH_MAX_SIZE + PSI_FILENAME_MAX_SIZE]; /* We manipulate plugin continuation data from a separate thread. Grab mutex to avoid concurrent access */ TSMutexLock(TSContMutexGet(contp)); data = TSContDataGet(contp); TSAssert(data->magic == MAGIC_ALIVE); if (!data->psi_buffer) { data->psi_buffer = TSIOBufferCreate(); data->psi_reader = TSIOBufferReaderAlloc(data->psi_buffer); } /* For security reason, we do not allow to include files that are not in the directory <plugin_path>/include. Also include file cannot contain any path. */ sprintf(inc_file, "%s/%s", psi_directory, _basename(data->psi_filename)); /* Read the include file and copy content into iobuffer */ if ((filep = TSfopen(inc_file, "r")) != NULL) { TSDebug(DBG_TAG, "Reading include file %s", inc_file); while (TSfgets(filep, buf, BUFFER_SIZE) != NULL) { TSIOBufferBlock block; int64_t len, avail, ndone, ntodo, towrite; char *ptr_block; len = strlen(buf); ndone = 0; ntodo = len; while (ntodo > 0) { /* TSIOBufferStart allocates more blocks if required */ block = TSIOBufferStart(data->psi_buffer); ptr_block = TSIOBufferBlockWriteStart(block, &avail); towrite = MIN(ntodo, avail); memcpy(ptr_block, buf + ndone, towrite); TSIOBufferProduce(data->psi_buffer, towrite); ntodo -= towrite; ndone += towrite; } } TSfclose(filep); data->psi_success = 1; if (log) { TSTextLogObjectWrite(log, "Successfully included file: %s", inc_file); } } else { data->psi_success = 0; if (log) { TSTextLogObjectWrite(log, "Failed to include file: %s", inc_file); } } /* Change state and schedule an event EVENT_IMMEDIATE on the plugin continuation to let it know we're done. */ /* Note: if the blocking call was not in the transformation state (i.e. in TS_HTTP_READ_REQUEST_HDR, TS_HTTP_OS_DNS and so on...) we could use TSHttpTxnReenable to wake up the transaction instead of sending an event. */ TSContSchedule(contp, 0, TS_THREAD_POOL_DEFAULT); data->psi_success = 0; data->state = STATE_READ_DATA; TSMutexUnlock(TSContMutexGet(contp)); return 0; }
static pr_list* load_config_file(const char *config_file) { char buffer[1024]; char default_config_file[1024]; TSFile fh; pr_list *prl = TSmalloc(sizeof(pr_list)); prl->patterncount = 0; /* locations in a config file line, end of line, split start, split end */ char *eol, *spstart, *spend; int lineno = 0; int retval; regex_info *info = 0; if (!config_file) { /* Default config file of plugins/cacheurl.config */ sprintf(default_config_file, "%s/cacheurl.config", TSPluginDirGet()); config_file = (const char *)default_config_file; } TSDebug(PLUGIN_NAME, "Opening config file: %s", config_file); fh = TSfopen(config_file, "r"); if (!fh) { TSError("[%s] Unable to open %s. No patterns will be loaded\n", PLUGIN_NAME, config_file); return prl; } while (TSfgets(fh, buffer, sizeof(buffer) - 1)) { lineno++; if (*buffer == '#') { /* # Comments, only at line beginning */ continue; } eol = strstr(buffer, "\n"); if (eol) { *eol = 0; /* Terminate string at newline */ } else { /* Malformed line - skip */ continue; } /* Split line into two parts based on whitespace */ /* Find first whitespace */ spstart = strstr(buffer, " "); if (!spstart) { spstart = strstr(buffer, "\t"); } if (!spstart) { TSError("[%s] ERROR: Invalid format on line %d. Skipping\n", PLUGIN_NAME, lineno); continue; } /* Find part of the line after any whitespace */ spend = spstart + 1; while(*spend == ' ' || *spend == '\t') { spend++; } if (*spend == 0) { /* We reached the end of the string without any non-whitepace */ TSError("[%s] ERROR: Invalid format on line %d. Skipping\n", PLUGIN_NAME, lineno); continue; } *spstart = 0; /* We have the pattern/replacement, now do precompilation. * buffer is the first part of the line. spend is the second part just * after the whitespace */ if (log) { TSTextLogObjectWrite(log, "Adding pattern/replacement pair: '%s' -> '%s'", buffer, spend); } TSDebug(PLUGIN_NAME, "Adding pattern/replacement pair: '%s' -> '%s'\n", buffer, spend); retval = regex_compile(&info, buffer, spend); if (!retval) { TSError("[%s] Error precompiling regex/replacement. Skipping.\n", PLUGIN_NAME); } // TODO - remove patterncount and make pr_list infinite (linked list) if (prl->patterncount >= PATTERNCOUNT) { TSError("[%s] Warning, too many patterns - skipping the rest" "(max: %d)\n", PLUGIN_NAME, PATTERNCOUNT); TSfree(info); break; } prl->pr[prl->patterncount] = info; prl->patterncount++; } TSfclose(fh); // Make sure the last element is null if (prl->patterncount < PATTERNCOUNT) { prl->pr[prl->patterncount] = NULL; } return prl; }