int ndmbstf_next(FILE* fp, /* the file to search */ char* key, /* what we're looking for */ char* buf, /* returned line */ unsigned max_buf) /* maximum lenght of buf (sizeof (buf)) */ { int rc, buf_len; /* * Read the next line up into buf[]. */ buf_len = ndmbstf_getline(fp, buf, max_buf); if (buf_len <= 0) { if (buf_len == EOF) return EOF; /* at end of file */ return -2; /* malformed line */ } rc = ndmbstf_compare(key, buf); if (rc == 0) { /* match */ return buf_len; } else { return 0; /* have line but it doesn't match */ } }
int jndex_fetch_post_backup_data_env (FILE *fp) { int rc; char buf[512]; char * p; char * q; ndmp9_pval pv; rc = ndmbstf_first (fp, "DE ", buf, sizeof buf); if (rc <= 0) { return rc; /* error or not found */ } /* DE HIST=Yes */ while (buf[0] == 'D' && buf[1] == 'E' && buf[2] == ' ') { if (ji_environment.n_env >= NDM_MAX_ENV) { goto overflow; } p = &buf[2]; while (*p == ' ') p++; if (!strchr (p, '=')) { goto malformed; } q = strchr (p, '='); if (!q) { goto malformed; } *q++ = 0; pv.name = p; pv.value = q; ndma_store_env_list (&ji_environment, &pv); rc = ndmbstf_getline (fp, buf, sizeof buf); if (rc <= 0) { break; } continue; malformed: ndmjob_log (1, "Malformed in -J%s: %s", J_index_file, buf); continue; overflow: ndmjob_log (1, "Overflow in -J%s: %s", J_index_file, buf); } return 0; }
int jndex_fetch_post_backup_data_env (FILE *fp) { int rc; char buf[512]; char * p; char * q; rc = ndmbstf_first (fp, "DE ", buf, sizeof buf); if (rc <= 0) { return rc; /* error or not found */ } /* DE HIST=Yes */ while (buf[0] == 'D' && buf[1] == 'E' && buf[2] == ' ') { if (n_ji_environment >= NDM_MAX_ENV) { goto overflow; } p = &buf[2]; while (*p == ' ') p++; if (!strchr (p, '=')) { goto malformed; } p = NDMOS_API_STRDUP (p); q = strchr (p, '='); *q++ = 0; ji_environment[n_ji_environment].name = p; ji_environment[n_ji_environment].value = q; n_ji_environment++; rc = ndmbstf_getline (fp, buf, sizeof buf); if (rc <= 0) { break; } continue; malformed: ndmjob_log (1, "Malformed in -J%s: %s", J_index_file, buf); continue; overflow: ndmjob_log (1, "Overflow in -J%s: %s", J_index_file, buf); } return 0; }
int jndex_fetch_post_backup_media (FILE *fp) { int rc; char buf[512]; rc = ndmbstf_first (fp, "CM ", buf, sizeof buf); if (rc <= 0) { return rc; /* error or not found */ } /* CM 01 T103/10850K */ while (buf[0] == 'C' && buf[1] == 'M' && buf[2] == ' ') { struct ndmmedia * me; if (n_ji_media >= NDM_MAX_MEDIA) { goto overflow; } me = &ji_media[n_ji_media]; if (ndmmedia_from_str (me, &buf[6])) { goto malformed; } n_ji_media++; rc = ndmbstf_getline (fp, buf, sizeof buf); if (rc <= 0) { break; } continue; malformed: ndmjob_log (1, "Malformed in -J%s: %s", J_index_file, buf); continue; overflow: ndmjob_log (1, "Overflow in -J%s: %s", J_index_file, buf); } return 0; }
int ndmbstf_first_with_bounds( FILE* fp, /* the file to search */ char* key, /* what we're looking for */ char* buf, /* returned line */ unsigned max_buf, /* maximum lenght of buf (sizeof (buf)) */ off_t lower_bound, /* offset, to skip headers, usually 0 */ off_t upper_bound) /* 0->don't know, >0 limit */ { off_t off; off_t lower, upper; /* bounds */ off_t delta; int rc, buf_len; if (upper_bound == 0) { off_t end_off; /* * Determine the file size using fseek()/ftell() */ fseeko(fp, 0, SEEK_END); end_off = ftello(fp); if (end_off == -1) return -3; upper_bound = end_off; } /* * Set lower and upper bounds of the binary search */ lower = lower_bound; upper = upper_bound; for (;;) { /* * Determine the delta (distance) between the current * lower and upper bounds. If delta is small, it is more * efficient to do a linear search than to continue * seeking. This is because stdio will pre-read * portions no matter what and fseek()ing will discard * the pre-read portions. MIN_DELTA is the approximation * of the stdio pre-read size. Better to just * linearly process the pre-read portion in the * hopes that our answer is already sitting in the * stdio buffer. */ delta = upper - lower; if (delta <= MIN_DELTA) break; /* * Seek to the first line after the midpoint * between the lower and upper bounds. */ off = lower + delta / 2; rc = ndmbstf_seek_and_align(fp, &off); if (rc < 0) { if (rc == EOF) { /* * Alignment found a very long line without * a \n at the end of the file. All we * can do now is try a linear search * from the current lower bound. */ } return -4; /* fseek() for hop failed */ } /* * Read the next line up into buf[]. */ buf_len = ndmbstf_getline(fp, buf, max_buf); if (buf_len <= 0) { /* * EOF, or malformed line. All we can do now * is try a linear search from the current * lower bound. */ break; } /* * This is the crucial point. * * buf[] contains a line just read. * off points the the line we just read. * key[] is what we're looking for. * * Is the objective line (what we're trying to find) * somewhere between lower..off or between off..upper. */ rc = ndmbstf_compare(key, buf); if (rc > 0) { /* key>buf. Objective somewhere in off..upper */ lower = off; } else { /* * key<=buf. Objective somewhere in lower..off * Notice that if key==buf, there still might * be a line ==key before the one we just * read. There might be hundreds of such * lines. The objective is the FIRST line * greater than or equal to the key. * This might be it. It might not. * So, keep searching. */ upper = off; } } /* * Do an unbounded linear search begining at the * lower bound. */ off = lower; rc = ndmbstf_seek_and_align(fp, &off); if (rc < 0) { if (rc == EOF) { /* * Alignment found a very long line without * a \n at the end of the file. All we * can do is give up. */ return -2; } return -4; /* fseek() for hop failed */ } /* * Read the next line up into buf[]. */ for (;;) { buf_len = ndmbstf_getline(fp, buf, max_buf); if (buf_len <= 0) { if (buf_len == EOF) break; /* at end of file */ return -2; } rc = ndmbstf_compare(key, buf); if (rc == 0) { /* match */ return buf_len; } if (rc < 0) return 0; /* have line but it doesn't match */ } return EOF; }