/***********************************************************************//** * @brief Get application parameters * * Get all task parameters from parameter file or (if required) by querying * the user. The parameters are read in the correct order. ***************************************************************************/ void ctexpcube::get_parameters(void) { // Setup observations from "inobs" parameter. Do not accept counts cubes. setup_observations(m_obs, true, true, false); // Get the incube filename std::string incube = (*this)["incube"].filename(); // If the "incube" file name is valid then setup the exposure cube from // the counts cube. Otherwise create a counts cube from the user // parameters GCTAEventCube cube = is_valid_filename(incube) ? GCTAEventCube(incube) : create_cube(m_obs); // Define exposure cube m_expcube = GCTACubeExposure(cube); // Get remaining parameters m_addbounds = (*this)["addbounds"].boolean(); m_publish = (*this)["publish"].boolean(); m_chatter = static_cast<GChatter>((*this)["chatter"].integer()); // Read output filename (if needed) if (read_ahead()) { m_outcube = (*this)["outcube"].filename(); } // Write parameters into logger log_parameters(TERSE); // Return return; }
/***********************************************************************//** * @brief Get application parameters * * Get all task parameters from parameter file or (if required) by querying * the user. Most parameters are only required if no observation exists so * far in the observation container. In this case, a single CTA observation * will be added to the container, using the definition provided in the * parameter file. ***************************************************************************/ void ctbin::get_parameters(void) { // If there are no observations in container then load them via user // parameters if (m_obs.size() == 0) { // Throw exception if no input observation file is given require_inobs(G_GET_PARAMETERS); // Get observation container without response (not needed) m_obs = get_observations(false); } // endif: there was no observation in the container // Create an event cube based on task parameters GCTAEventCube cube = create_cube(m_obs); // Get the skymap from the cube and initialise all pixels to zero m_cube = cube.map(); m_cube = 0.0; // Get energy boundaries m_ebounds = cube.ebounds(); // Optionally read ahead parameters so that they get correctly // dumped into the log file if (read_ahead()) { m_outcube = (*this)["outcube"].filename(); } // Return return; }
/***********************************************************************//** * @brief Get application parameters * * Get all required task parameters from the parameter file or (if specified) * by querying the user. Observation dependent parameters will only be read * if the observation container is actually empty. Observation dependent * parameters are: * "stat" (statistics to be used for observation), * "caldb" (calibration database), * "irf" (instrument response function), and * "infile" (input file name). * The model will only be loaded if no model components exist in the * observation container. * * This method handles both loading of FITS files and of handling XML * observation definition files. ***************************************************************************/ void ctlike::get_parameters(void) { // If there are no observations in container then load them via user // parameters if (m_obs.size() == 0) { // Throw exception if no input observation file is given require_inobs(G_GET_PARAMETERS); // Get observation container m_obs = get_observations(); } // endif: there was no observation in the container // If only single observation is used, read statistics parameter if (!m_use_xml) { // Get other task parameters std::string statistics = gammalib::toupper((*this)["stat"].string()); // Set statistics (*m_obs[0]).statistics(statistics); } // If there is are no models associated with the observations then // load now the model definition if (m_obs.models().size() == 0) { // Get models XML filename std::string filename = (*this)["inmodel"].filename(); // Setup models for optimizing. m_obs.models(GModels(filename)); } // endif: no models were associated with observations // Get other parameters m_refit = (*this)["refit"].boolean(); m_apply_edisp = (*this)["edisp"].boolean(); m_fix_spat_for_ts = (*this)["fix_spat_for_ts"].boolean(); // Optionally read ahead parameters so that they get correctly // dumped into the log file if (read_ahead()) { m_outmodel = (*this)["outmodel"].filename(); } // Set optimizer logger if (logTerse()) { static_cast<GOptimizerLM*>(m_opt)->logger(&log); } else { static_cast<GOptimizerLM*>(m_opt)->logger(NULL); } // Return return; }
/***********************************************************************//** * @brief Get application parameters * * Get all task parameters from parameter file or (if required) by querying * the user. The parameters are read in the correct order. ***************************************************************************/ void ctpsfcube::get_parameters(void) { // If there are no observations in container then load them via user // parameters if (m_obs.size() == 0) { // Throw exception if no input observation file is given require_inobs(G_GET_PARAMETERS); // Build observation container m_obs = get_observations(); } // endif: there was no observation in the container // Get the incube filename std::string incube = (*this)["incube"].filename(); // Get additional binning parameters double amax = (*this)["amax"].real(); int anumbins = (*this)["anumbins"].integer(); // Check for filename validity if ((incube == "NONE") || (gammalib::strip_whitespace(incube) == "")) { // Create an event cube based on task parameters GCTAEventCube cube = create_cube(m_obs); // Define psf cube m_psfcube = GCTACubePsf(cube, amax, anumbins); } // ... otherwise setup the exposure cube from the counts map else { // Load event cube from filename GCTAEventCube cube(incube); // Define psf cube m_psfcube = GCTACubePsf(cube, amax, anumbins); } // endelse: cube loaded from file // Read energy dispersion flag m_apply_edisp = (*this)["edisp"].boolean(); // Read output filename (if needed) if (read_ahead()) { m_outcube = (*this)["outcube"].filename(); } // Return return; }
/*===========================================================================* * main * *===========================================================================*/ PUBLIC int main(int argc, char *argv[]) { /* This is the main routine of this service. The main loop consists of * three major activities: getting new work, processing the work, and * sending the reply. The loop never terminates, unless a panic occurs. */ int error, ind; unsigned short test_endian = 1; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); le_CPU = (*(unsigned char *) &test_endian == 0 ? 0 : 1); /* Server isn't tested on big endian CPU */ ASSERT(le_CPU == 1); while(!unmountdone || !exitsignaled) { endpoint_t src; /* Wait for request message. */ get_work(&fs_m_in); src = fs_m_in.m_source; error = OK; caller_uid = INVAL_UID; /* To trap errors */ caller_gid = INVAL_GID; req_nr = fs_m_in.m_type; if (req_nr < VFS_BASE) { fs_m_in.m_type += VFS_BASE; req_nr = fs_m_in.m_type; } ind = req_nr - VFS_BASE; if (ind < 0 || ind >= NREQS) { printf("mfs: bad request %d\n", req_nr); printf("ind = %d\n", ind); error = EINVAL; } else { error = (*fs_call_vec[ind])(); /*cch_check();*/ } fs_m_out.m_type = error; reply(src, &fs_m_out); if (error == OK) read_ahead(); /* do block read ahead */ } }
/* Have emptied current buffer by sending to net and getting ack. Free it and return next buffer filled with data. */ int readit(PIO_CONTEXT pio_context, struct tftphdr **dpp, int convert) /*__fn__ */ { struct bf *b; bfs[current].counter = BF_FREE; /* free old one */ current = !current; /* "incr" current */ b = &bfs[current]; /* look at new buffer */ if (b->counter == BF_FREE) /* if it's empty */ read_ahead(pio_context, convert); /* fill it */ *dpp = (struct tftphdr *)b->buf; /* set caller's ptr */ return b->counter; }
/* Have emptied current buffer by sending to net and getting ack. Free it and return next buffer filled with data. */ int readit(FILE * file, struct tftphdr **dpp, int convert) { struct bf *b; bfs[current].counter = BF_FREE; /* free old one */ current = !current; /* "incr" current */ b = &bfs[current]; /* look at new buffer */ if (b->counter == BF_FREE) /* if it's empty */ read_ahead(file, convert); /* fill it */ /* assert(b->counter != BF_FREE);*//* check */ *dpp = (struct tftphdr *)b->buf; /* set caller's ptr */ return b->counter; }
struct OperatorTableEntry *Scanner::lookup_op() { char buf[4]; buf[0] = cur_char(); buf[1] = next_char(); buf[2] = read_ahead(2); buf[3] = 0; for (struct OperatorTableEntry *op = op_tab; op->str; op++) { int len = strlen(op->str); if (!strncmp(op->str, buf, len)) { return op; } } return 0; }
/* Have emptied current buffer by sending to net and getting ack. Free it and return next buffer filled with data. */ static int readit(struct testcase *test, struct tftphdr **dpp, int convert /* if true, convert to ascii */) { struct bf *b; bfs[current].counter = BF_FREE; /* free old one */ current = !current; /* "incr" current */ b = &bfs[current]; /* look at new buffer */ if (b->counter == BF_FREE) /* if it's empty */ read_ahead(test, convert); /* fill it */ *dpp = (struct tftphdr *)b->buf; /* set caller's ptr */ return b->counter; }
/*===========================================================================* * main * *===========================================================================*/ PUBLIC int main(int argc, char *argv[]) { /* This is the main routine of this service. The main loop consists of * three major activities: getting new work, processing the work, and * sending the reply. The loop never terminates, unless a panic occurs. */ int error, ind; message m; /* Initialize the server, then go to work. */ init_server(); fs_m_in.m_type = FS_READY; if (send(FS_PROC_NR, &fs_m_in) != OK) { printf("MFS(%d): Error sending login to VFS\n", SELF_E); return -1; } while(!unmountdone || !exitsignaled) { endpoint_t src; /* Wait for request message. */ get_work(&fs_m_in); src = fs_m_in.m_source; error = OK; caller_uid = -1; /* To trap errors */ caller_gid = -1; /* Exit request? */ if(src == PM_PROC_NR) { exitsignaled = 1; fs_sync(); continue; } /* This must be a regular VFS request. */ assert(src == VFS_PROC_NR && !unmountdone); req_nr = fs_m_in.m_type; if (req_nr < VFS_BASE) { fs_m_in.m_type += VFS_BASE; req_nr = fs_m_in.m_type; } ind= req_nr-VFS_BASE; if (ind < 0 || ind >= NREQS) { printf("mfs: bad request %d\n", req_nr); printf("ind = %d\n", ind); error = EINVAL; } else { error = (*fs_call_vec[ind])(); /*cch_check();*/ } fs_m_out.m_type = error; reply(src, &fs_m_out); if (error == OK && rdahed_inode != NIL_INODE) { read_ahead(); /* do block read ahead */ } } }
/* * Send the requested file. */ void xmitfile(struct formats *pf) { struct tftphdr *dp; struct tftphdr *ap; /* ack packet */ int size, n; volatile unsigned short block; signal(SIGALRM, timer); dp = r_init(); ap = (struct tftphdr *)ackbuf; block = 1; do { size = readit(file, &dp, pf->f_convert); if (size < 0) { nak(errno + 100); goto abort; } dp->th_opcode = htons((u_short)DATA); dp->th_block = htons((u_short)block); timeouts = 0; (void)setjmp(timeoutbuf); send_data: { int i, t = 1; for (i = 0; ; i++){ if (send(peer, dp, size + 4, 0) != size + 4) { sleep(t); t = (t < 32) ? t<< 1 : t; if (i >= 12) { syslog(LOG_ERR, "write: %m"); goto abort; } } break; } } read_ahead(file, pf->f_convert); for ( ; ; ) { alarm(rexmtval); /* read the ack */ n = recv(peer, ackbuf, sizeof (ackbuf), 0); alarm(0); if (n < 0) { syslog(LOG_ERR, "read: %m"); goto abort; } ap->th_opcode = ntohs((u_short)ap->th_opcode); ap->th_block = ntohs((u_short)ap->th_block); if (ap->th_opcode == ERROR) goto abort; if (ap->th_opcode == ACK) { if (ap->th_block == block) break; /* Re-synchronize with the other side */ (void) synchnet(peer); if (ap->th_block == (block -1)) goto send_data; } } block++; } while (size == SEGSIZE); abort: (void) fclose(file); }
/* * Send the requested file. */ static void sendtftp(struct testcase *test, struct formats *pf) { int size; ssize_t n; sendblock = 1; #if defined(HAVE_ALARM) && defined(SIGALRM) mysignal(SIGALRM, timer); #endif sdp = r_init(); sap = (struct tftphdr *)ackbuf; do { size = readit(test, &sdp, pf->f_convert); if (size < 0) { nak(ERRNO + 100); return; } sdp->th_opcode = htons((u_short)opcode_DATA); sdp->th_block = htons((u_short)sendblock); timeout = 0; #ifdef HAVE_SIGSETJMP (void) sigsetjmp(timeoutbuf, 1); #endif send_data: if (swrite(peer, sdp, size + 4) != size + 4) { logmsg("write"); return; } read_ahead(test, pf->f_convert); for ( ; ; ) { #ifdef HAVE_ALARM alarm(rexmtval); /* read the ack */ #endif n = sread(peer, ackbuf, sizeof (ackbuf)); #ifdef HAVE_ALARM alarm(0); #endif if (n < 0) { logmsg("read: fail"); return; } sap->th_opcode = ntohs((u_short)sap->th_opcode); sap->th_block = ntohs((u_short)sap->th_block); if (sap->th_opcode == opcode_ERROR) { logmsg("got ERROR"); return; } if (sap->th_opcode == opcode_ACK) { if (sap->th_block == sendblock) { break; } /* Re-synchronize with the other side */ (void) synchnet(peer); if (sap->th_block == (sendblock-1)) { goto send_data; } } } sendblock++; } while (size == SEGSIZE); }
/***********************************************************************//** * @brief Simulate event data * * This method runs the simulation. Results are not saved by this method. * Invoke "save" to save the results. ***************************************************************************/ void ctobssim::run(void) { // Switch screen logging on in debug mode if (logDebug()) { log.cout(true); } // Get parameters get_parameters(); // Write input parameters into logger if (logTerse()) { log_parameters(); log << std::endl; } // Special mode: if read ahead is specified we know that we called // the execute() method, hence files are saved immediately and event // lists are disposed afterwards. if (read_ahead()) { m_save_and_dispose = true; } // Determine the number of valid CTA observations, set energy dispersion flag // for all CTA observations and save old values in save_edisp vector int n_observations = 0; std::vector<bool> save_edisp; save_edisp.assign(m_obs.size(), false); for (int i = 0; i < m_obs.size(); ++i) { GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]); if (obs != NULL) { save_edisp[i] = obs->response()->apply_edisp(); obs->response()->apply_edisp(m_apply_edisp); n_observations++; } } // If more than a single observation has been handled then make sure that // an XML file will be used for storage if (n_observations > 1) { m_use_xml = true; } // Write execution mode into logger if (logTerse()) { log << std::endl; log.header1("Execution mode"); log << gammalib::parformat("Event list management"); if (m_save_and_dispose) { log << "Save and dispose (reduces memory needs)" << std::endl; } else { log << "Keep events in memory" << std::endl; } log << gammalib::parformat("Output format"); if (m_use_xml) { log << "Write Observation Definition XML file" << std::endl; } else { log << "Write single event list FITS file" << std::endl; } } // Write seed values into logger if (logTerse()) { log << std::endl; log.header1("Seed values"); for (int i = 0; i < m_rans.size(); ++i) { log << gammalib::parformat("Seed "+gammalib::str(i)); log << gammalib::str(m_rans[i].seed()) << std::endl; } } // Write observation(s) into logger if (logTerse()) { log << std::endl; if (m_obs.size() > 1) { log.header1("Observations"); } else { log.header1("Observation"); } log << m_obs << std::endl; } // Write header if (logTerse()) { log << std::endl; if (m_obs.size() > 1) { log.header1("Simulate observations"); } else { log.header1("Simulate observation"); } } // From here on the code can be parallelized if OpenMP support // is enabled. The code in the following block corresponds to the // code that will be executed in each thread #pragma omp parallel { // Each thread will have it's own logger to avoid conflicts GLog wrklog; if (logDebug()) { wrklog.cout(true); } // Allocate and initialize copies for multi-threading GModels models(m_obs.models()); // Copy configuration from application logger to thread logger wrklog.date(log.date()); wrklog.name(log.name()); // Set a big value to avoid flushing wrklog.max_size(10000000); // Loop over all observation in the container. If OpenMP support // is enabled, this loop will be parallelized. #pragma omp for for (int i = 0; i < m_obs.size(); ++i) { // Get pointer on CTA observation GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]); // Continue only if observation is a CTA observation if (obs != NULL) { // Write header for observation if (logTerse()) { if (obs->name().length() > 1) { wrklog.header3("Observation "+obs->name()); } else { wrklog.header3("Observation"); } } // Work on a clone of the CTA observation. This makes sure that // any memory allocated for computing (for example a response // cache) is properly de-allocated on exit of this run GCTAObservation obs_clone = *obs; // Save number of events before entering simulation int events_before = obs_clone.events()->size(); // Simulate source events simulate_source(&obs_clone, models, m_rans[i], &wrklog); // Simulate source events simulate_background(&obs_clone, models, m_rans[i], &wrklog); // Dump simulation results if (logNormal()) { wrklog << gammalib::parformat("MC events"); wrklog << obs_clone.events()->size() - events_before; wrklog << " (all models)"; wrklog << std::endl; } // Append the event list to the original observation obs->events(*(obs_clone.events())); // If requested, event lists are saved immediately if (m_save_and_dispose) { // Set event output file name. If multiple observations are // handled, build the filename from prefix and observation // index. Otherwise use the outfile parameter. std::string outfile; if (m_use_xml) { m_prefix = (*this)["prefix"].string(); outfile = m_prefix + gammalib::str(i) + ".fits"; } else { outfile = (*this)["outevents"].filename(); } // Store output file name in original observation obs->eventfile(outfile); // Save observation into FITS file. This is a critical zone // to avoid multiple threads writing simultaneously #pragma omp critical { obs_clone.save(outfile, clobber()); } // Dispose events obs->dispose_events(); } // ... otherwise append the event list to the original observation /* else { obs->events(*(obs_clone.events())); } */ } // endif: CTA observation found } // endfor: looped over observations // At the end, the content of the thread logger is added to // the application logger #pragma omp critical (log) { log << wrklog; } } // end pragma omp parallel // Restore energy dispersion flag for all CTA observations for (int i = 0; i < m_obs.size(); ++i) { GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[i]); if (obs != NULL) { obs->response()->apply_edisp(save_edisp[i]); } } // Return return; }
/***********************************************************************//** * @brief Get application parameters * * Get all task parameters from parameter file or (if required) by querying * the user. Most parameters are only required if no observation exists so * far in the observation container. In this case, a single CTA observation * will be added to the container, using the definition provided in the * parameter file. ***************************************************************************/ void ctobssim::get_parameters(void) { // Initialise seed vector m_rans.clear(); // If there are no observations in container then load them via user // parameters if (m_obs.size() == 0) { m_obs = get_observations(); } // ... otherwise make sure that observation boundaries are set else { set_obs_bounds(m_obs); } // Read model definition file if required if (m_obs.models().size() == 0) { std::string inmodel = (*this)["inmodel"].filename(); m_obs.models(inmodel); } // Get other parameters m_seed = (*this)["seed"].integer(); m_apply_edisp = (*this)["edisp"].boolean(); m_max_rate = (*this)["maxrate"].real(); // Optionally read ahead parameters so that they get correctly // dumped into the log file if (read_ahead()) { m_outevents = (*this)["outevents"].filename(); m_prefix = (*this)["prefix"].string(); } // Initialise random number generators. We initialise here one random // number generator per observation so that each observation will // get it's own random number generator. This will lead to identical // results independently of code parallelization with OpenMP. The // seeds for all random number generators are derived randomly but // fully deterministacally from the seed parameter, so that a given // seed parameter leads always to the same set of simulated events, and // this independently of parallelization. // Get a random number generator for seed determination GRan master(m_seed); // Allocate vector of random number generator seeds std::vector<unsigned long long int> seeds; // Loop over all observations in the container for (int i = 0; i < m_obs.size(); ++i) { // Allocate new seed value unsigned long long int new_seed; // Determine new seed value. We make sure that the new seed // value has not been used already for another observation. bool repeat = false; do { new_seed = (unsigned long long int)(master.uniform() * 1.0e10) + m_seed; repeat = false; for (int j = 0; j < seeds.size(); ++j) { if (new_seed == seeds[j]) { repeat = true; break; } } } while(repeat); // Add the seed to the vector for bookkeeping seeds.push_back(new_seed); // Use the seed to create a random number generator for the // actual observation m_rans.push_back(GRan(new_seed)); } // endfor: looped over observations // Return return; }
/*===========================================================================* * main * *===========================================================================*/ PUBLIC int main(int argc, char *argv[]) { /* This is the main routine of this service. The main loop consists of * three major activities: getting new work, processing the work, and * sending the reply. The loop never terminates, unless a panic occurs. */ int error = OK, ind, transid; unsigned short test_endian = 1; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); le_CPU = (*(unsigned char *) &test_endian == 0 ? 0 : 1); /* Server isn't tested on big endian CPU */ ASSERT(le_CPU == 1); while(!unmountdone || !exitsignaled) { endpoint_t src; /* Wait for request message. */ get_work(&fs_m_in); transid = TRNS_GET_ID(fs_m_in.m_type); fs_m_in.m_type = TRNS_DEL_ID(fs_m_in.m_type); if (fs_m_in.m_type == 0) { assert(!IS_VFS_FS_TRANSID(transid)); fs_m_in.m_type = transid; /* Backwards compat. */ transid = 0; } else assert(IS_VFS_FS_TRANSID(transid)); src = fs_m_in.m_source; caller_uid = INVAL_UID; /* To trap errors */ caller_gid = INVAL_GID; req_nr = fs_m_in.m_type; if (req_nr < VFS_BASE) { fs_m_in.m_type += VFS_BASE; req_nr = fs_m_in.m_type; } ind = req_nr - VFS_BASE; if (ind < 0 || ind >= NREQS) { printf("mfs: bad request %d\n", req_nr); printf("ind = %d\n", ind); error = EINVAL; } else { error = (*fs_call_vec[ind])(); } fs_m_out.m_type = error; if (IS_VFS_FS_TRANSID(transid)) { /* If a transaction ID was set, reset it */ fs_m_out.m_type = TRNS_ADD_ID(fs_m_out.m_type, transid); } reply(src, &fs_m_out); if (error == OK) read_ahead(); /* do block read ahead */ } return 0; }
/* * Send the requested file. */ static void sendtftp(struct testcase *test, struct formats *pf) { struct tftphdr *dp; struct tftphdr *ap; /* ack packet */ unsigned short block = 1; int size, n; #if defined(HAVE_ALARM) && defined(SIGALRM) mysignal(SIGALRM, timer); #endif dp = r_init(); ap = (struct tftphdr *)ackbuf; do { size = readit(test, &dp, pf->f_convert); if (size < 0) { nak(errno + 100); return; } dp->th_opcode = htons((u_short)DATA); dp->th_block = htons((u_short)block); timeout = 0; #ifdef HAVE_SIGSETJMP (void) sigsetjmp(timeoutbuf, 1); #endif send_data: if (send(peer, dp, size + 4, 0) != size + 4) { logmsg("write\n"); return; } read_ahead(test, pf->f_convert); for ( ; ; ) { #ifdef HAVE_ALARM alarm(rexmtval); /* read the ack */ #endif n = recv(peer, ackbuf, sizeof (ackbuf), 0); #ifdef HAVE_ALARM alarm(0); #endif if (n < 0) { logmsg("read: fail\n"); return; } ap->th_opcode = ntohs((u_short)ap->th_opcode); ap->th_block = ntohs((u_short)ap->th_block); if (ap->th_opcode == ERROR) { logmsg("got ERROR"); return; } if (ap->th_opcode == ACK) { if (ap->th_block == block) { break; } /* Re-synchronize with the other side */ (void) synchnet(peer); if (ap->th_block == (block -1)) { goto send_data; } } } block++; } while (size == SEGSIZE); }
/* * Send the requested file. */ void sendfile(int fd, char *name, char *mode) { register struct tftphdr *ap; /* data and ack packets */ struct tftphdr *dp; volatile int block = 0, size = 0; int n; volatile unsigned long amount = 0; struct sockaddr_in from; socklen_t fromlen; volatile int convert; /* true if doing nl->crlf conversion */ FILE *file; startclock(); /* start stat's clock */ dp = r_init(); /* reset fillbuf/read-ahead code */ ap = (struct tftphdr *)ackbuf; file = fdopen(fd, "r"); convert = !strcmp(mode, "netascii"); signal(SIGALRM, timer); do { if (block == 0) size = makerequest(WRQ, name, dp, mode) - 4; else { /* size = read(fd, dp->th_data, SEGSIZE); */ size = readit(file, &dp, convert); if (size < 0) { nak(errno + 100); break; } dp->th_opcode = htons((u_short)DATA); dp->th_block = htons((u_short)block); } timeout = 0; (void) sigsetjmp(timeoutbuf, 1); send_data: if (trace) tpacket("sent", dp, size + 4); n = sendto(f, dp, size + 4, 0, (struct sockaddr *)&s_inn, sizeof(s_inn)); if (n != size + 4) { perror("tftp: sendto"); goto abort; } read_ahead(file, convert); for ( ; ; ) { alarm(rexmtval); do { fromlen = sizeof (from); n = recvfrom(f, ackbuf, sizeof (ackbuf), 0, (struct sockaddr *)&from, &fromlen); } while (n <= 0); alarm(0); if (n < 0) { perror("tftp: recvfrom"); goto abort; } s_inn.sin_port = from.sin_port; /* added */ if (trace) tpacket("received", ap, n); /* should verify packet came from server */ ap->th_opcode = ntohs(ap->th_opcode); ap->th_block = ntohs(ap->th_block); if (ap->th_opcode == ERROR) { printf("Error code %d: %s\n", ap->th_code, ap->th_msg); goto abort; } if (ap->th_opcode == ACK) { volatile int j = 0; if (ap->th_block == block) { break; } /* On an error, try to synchronize * both sides. */ j = synchnet(f); if (j && trace) { printf("discarded %d packets\n", j); } if (ap->th_block == (block-1)) { goto send_data; } } } if (block > 0) amount += size; block++; } while (size == SEGSIZE || block == 1); abort: fclose(file); stopclock(); if (amount > 0) printstats("Sent", amount); }
/* * Send the requested file. */ static void sendtftp(struct testcase *test, struct formats *pf) { int size; ssize_t n; /* These are volatile to live through a siglongjmp */ volatile unsigned short sendblock; /* block count */ struct tftphdr * volatile sdp = r_init(); /* data buffer */ struct tftphdr * const sap = &ackbuf.hdr; /* ack buffer */ sendblock = 1; #if defined(HAVE_ALARM) && defined(SIGALRM) mysignal(SIGALRM, timer); #endif do { size = readit(test, (struct tftphdr **)&sdp, pf->f_convert); if(size < 0) { nak(errno + 100); return; } sdp->th_opcode = htons((unsigned short)opcode_DATA); sdp->th_block = htons(sendblock); timeout = 0; #ifdef HAVE_SIGSETJMP (void) sigsetjmp(timeoutbuf, 1); #endif if(test->writedelay) { logmsg("Pausing %d seconds before %d bytes", test->writedelay, size); wait_ms(1000*test->writedelay); } send_data: if(swrite(peer, sdp, size + 4) != size + 4) { logmsg("write"); return; } read_ahead(test, pf->f_convert); for(;;) { #ifdef HAVE_ALARM alarm(rexmtval); /* read the ack */ #endif n = sread(peer, &ackbuf.storage[0], sizeof(ackbuf.storage)); #ifdef HAVE_ALARM alarm(0); #endif if(got_exit_signal) return; if(n < 0) { logmsg("read: fail"); return; } sap->th_opcode = ntohs((unsigned short)sap->th_opcode); sap->th_block = ntohs(sap->th_block); if(sap->th_opcode == opcode_ERROR) { logmsg("got ERROR"); return; } if(sap->th_opcode == opcode_ACK) { if(sap->th_block == sendblock) { break; } /* Re-synchronize with the other side */ (void) synchnet(peer); if(sap->th_block == (sendblock-1)) { goto send_data; } } } sendblock++; } while(size == SEGSIZE); }
char Scanner::next_char() { return read_ahead(1); }
/* * Send the requested file. */ void send_file (struct formats *pf) { struct tftphdr *dp, *r_init (); register struct tftphdr *ap; /* ack packet */ register int size, n; volatile int block; signal (SIGALRM, timer); dp = r_init (); ap = (struct tftphdr *) ackbuf; block = 1; do { size = readit (file, &dp, pf->f_convert); if (size < 0) { nak (errno + 100); goto abort; } dp->th_opcode = htons ((u_short) DATA); dp->th_block = htons ((u_short) block); timeout = 0; setjmp (timeoutbuf); send_data: if (send (peer, (const char *) dp, size + 4, 0) != size + 4) { syslog (LOG_ERR, "tftpd: write: %m\n"); goto abort; } read_ahead (file, pf->f_convert); for (;;) { alarm (rexmtval); /* read the ack */ n = recv (peer, ackbuf, sizeof (ackbuf), 0); alarm (0); if (n < 0) { syslog (LOG_ERR, "tftpd: read: %m\n"); goto abort; } ap->th_opcode = ntohs ((u_short) ap->th_opcode); ap->th_block = ntohs ((u_short) ap->th_block); if (ap->th_opcode == ERROR) goto abort; if (ap->th_opcode == ACK) { if ((u_short) ap->th_block == (u_short) block) break; /* Re-synchronize with the other side */ synchnet (peer); if ((u_short) ap->th_block == (u_short) (block - 1)) goto send_data; } } block++; } while (size == SEGSIZE); abort: fclose (file); }
/*===========================================================================* * main * *===========================================================================*/ PUBLIC int main(void) { /* This is the main routine of this service. The main loop consists of * three major activities: getting new work, processing the work, and * sending the reply. The loop never terminates, unless a panic occurs. */ int who_e; /* caller */ int error, ind; message m; /* Initialize the server, then go to work. */ init_server(); fs_m_in.m_type = FS_READY; if (send(FS_PROC_NR, &fs_m_in) != OK) { printf("MFS(%d): Error sending login to VFS\n", SELF_E); return -1; } #if 0 if (fs_m_in.m_type != REQ_READSUPER_O && fs_m_in.m_type != REQ_READSUPER_S) { printf("MFS(%d): Invalid login reply\n", SELF_E); return -1; } else { if (fs_m_in.m_type == REQ_READSUPER_S) fs_m_out.m_type = fs_readsuper_s(); else fs_m_out.m_type = fs_readsuper_o(); reply(FS_PROC_NR, &fs_m_out); if (fs_m_out.m_type != OK) return -1; } #endif for (;;) { /* Wait for request message. */ get_work(&fs_m_in); error = OK; caller_uid = -1; /* To trap errors */ caller_gid = -1; who_e = fs_m_in.m_source; if (who_e != FS_PROC_NR) { if (who_e == 0) { /* printf("MFS(%d): MSG from PM\n", SELF_E); error = 1; fs_m_out.m_type = error; reply(who_e, &fs_m_out); */ } continue; } req_nr = fs_m_in.m_type; if (req_nr < VFS_BASE) { fs_m_in.m_type += VFS_BASE; req_nr = fs_m_in.m_type; } ind= req_nr-VFS_BASE; if (ind < 0 || ind >= NREQS) { printf("mfs: bad request %d\n", req_nr); printf("ind = %d\n", ind); error = EINVAL; } else { error = (*fs_call_vec[ind])(); /*cch_check();*/ } fs_m_out.m_type = error; reply(who_e, &fs_m_out); if (error == OK && rdahed_inode != NIL_INODE) { read_ahead(); /* do block read ahead */ } /* * VFS asks RS to bring down the FS... */ /* if (req_nr == REQ_UNMOUNT || (req_nr == REQ_READSUPER && error != OK)) { printf("MFS(%d) exit() cachehit: %d cachemiss: %d\n", SELF_E, inode_cache_hit, inode_cache_miss); return 0; } */ } }
/* * Send the requested file. */ int tftp_sendfile(int f, union sock_addr *peeraddr, int fd, const char *name, const char *mode) { struct tftphdr *ap; /* data and ack packets */ struct tftphdr *dp; int n; volatile int is_request; volatile u_short block; volatile int size, convert; volatile off_t amount; union sock_addr from; socklen_t fromlen; FILE *file; u_short ap_opcode, ap_block; startclock(); /* start stat's clock */ dp = r_init(); /* reset fillbuf/read-ahead code */ ap = (struct tftphdr *)ackbuf; convert = !strcmp(mode, "netascii"); file = fdopen(fd, convert ? "rt" : "rb"); block = 0; is_request = 1; /* First packet is the actual WRQ */ amount = 0; bsd_signal(SIGALRM, timer); do { if (is_request) { size = makerequest(WRQ, name, dp, mode) - 4; } else { /* size = read(fd, dp->th_data, SEGSIZE); */ size = readit(file, &dp, convert); if (size < 0) { nak(f, peeraddr, errno + 100, NULL); break; } dp->th_opcode = htons((u_short) DATA); dp->th_block = htons((u_short) block); } timeout = 0; (void)sigsetjmp(timeoutbuf, 1); if (trace) tpacket("sent", dp, size + 4); n = sendto(f, dp, size + 4, 0, &(peeraddr->sa), SOCKLEN(peeraddr)); if (n != size + 4) { perror("tftp: sendto"); goto abort; } read_ahead(file, convert); for (;;) { alarm(rexmtval); do { fromlen = sizeof(from); n = recvfrom(f, ackbuf, sizeof(ackbuf), 0, &from.sa, &fromlen); } while (n <= 0); alarm(0); if (n < 0) { perror("tftp: recvfrom"); goto abort; } sa_set_port(peeraddr, SOCKPORT(&from)); /* added */ if (trace) tpacket("received", ap, n); /* should verify packet came from server */ ap_opcode = ntohs((u_short) ap->th_opcode); ap_block = ntohs((u_short) ap->th_block); if (ap_opcode == ERROR) { printf("Error code %d: %s\n", ap_block, ap->th_msg); goto abort; } if (ap_opcode == ACK) { int j; if (ap_block == block) { break; } /* On an error, try to synchronize * both sides. */ j = synchnet(f); if (j && trace) { printf("discarded %d packets\n", j); } /* * RFC1129/RFC1350: We MUST NOT re-send the DATA * packet in response to an invalid ACK. Doing so * would cause the Sorcerer's Apprentice bug. */ } } if (!is_request) amount += size; is_request = 0; block++; } while (size == SEGSIZE || block == 1); abort: fclose(file); stopclock(); //if (amount > 0) // printstats("Sent", amount); return amount; }
/***********************************************************************//** * @brief Get application parameters * * Get all task parameters from parameter file or (if required) by querying * the user. The parameters are read in the correct order. ***************************************************************************/ void ctmodel::get_parameters(void) { // Reset cube append flag m_append_cube = false; // If there are no observations in container then load them via user // parameters. if (m_obs.size() == 0) { get_obs(); } // If we have now excactly one CTA observation (but no cube has yet been // appended to the observation) then check whether this observation // is a binned observation, and if yes, extract the counts cube for // model generation if ((m_obs.size() == 1) && (m_append_cube == false)) { // Get CTA observation GCTAObservation* obs = dynamic_cast<GCTAObservation*>(m_obs[0]); // Continue only if observation is a CTA observation if (obs != NULL) { // Check for binned observation if (obs->eventtype() == "CountsCube") { // Set cube from binned observation GCTAEventCube* evtcube = dynamic_cast<GCTAEventCube*>(const_cast<GEvents*>(obs->events())); cube(*evtcube); // Signal that cube has been set m_has_cube = true; // Signal that we are in binned mode m_binned = true; } // endif: observation was binned } // endif: observation was CTA } // endif: had exactly one observation // Read model definition file if required if (m_obs.models().size() == 0) { // Get model filename std::string inmodel = (*this)["inmodel"].filename(); // Load models from file m_obs.models(inmodel); } // endif: there were no models // Get energy dispersion flag parameters m_apply_edisp = (*this)["edisp"].boolean(); // If we do not have yet a counts cube for model computation then check // whether we should read it from the "incube" parameter or whether we // should create it from scratch using the task parameters if (!m_has_cube) { // Read cube definition file std::string incube = (*this)["incube"].filename(); // If no cube file has been specified then create a cube from // the task parameters ... if ((incube == "NONE") || (gammalib::strip_whitespace(incube) == "")) { // Create cube from scratch m_cube = create_cube(m_obs); } // ... otherwise load the cube from file and reset all bins // to zero else { // Load cube from given file m_cube.load(incube); // Set all cube bins to zero for (int i = 0; i < m_cube.size(); ++i) { m_cube[i]->counts(0.0); } } // Signal that cube has been set m_has_cube = true; } // endif: we had no cube yet // Read optionally output cube filenames if (read_ahead()) { m_outcube = (*this)["outcube"].filename(); } // If cube should be appended to first observation then do that now. // This is a kluge that makes sure that the cube is passed as part // of the observation in case that a cube response is used. The kluge // is needed because the GCTACubeSourceDiffuse::set method needs to // get the full event cube from the observation. It is also at this // step that the GTI, which may just be a dummy GTI when create_cube() // has been used, will be set. if (m_append_cube) { //TODO: Check that energy boundaries are compatible // Attach GTI of observations to model cube m_cube.gti(m_obs[0]->events()->gti()); // Attach model cube to observations m_obs[0]->events(m_cube); } // endif: cube was scheduled for appending // Return return; }