int omi_prc_set(omi_conn *cptr, char *xend, char *buff, char *bend) { int rv; omi_si replicate; omi_li li; mval v; /* Replicate flag */ OMI_SI_READ(&replicate, cptr->xptr); /* Global Ref */ OMI_LI_READ(&li, cptr->xptr); /* Condition handler for DBMS operations */ ESTABLISH_RET(omi_dbms_ch,0); rv = omi_gvextnam(cptr, li.value, cptr->xptr); /* If true, there was an error finding the global reference in the DBMS */ if (rv < 0) { REVERT; return rv; } cptr->xptr += li.value; /* Bounds checking */ if (cptr->xptr > xend) { REVERT; return -OMI_ER_PR_INVMSGFMT; } /* Global Data */ OMI_LI_READ(&li, cptr->xptr); v.mvtype = MV_STR; v.str.len = li.value; v.str.addr = cptr->xptr; op_gvput(&v); REVERT; cptr->xptr += li.value; /* Bounds checking */ if (cptr->xptr > xend) return -OMI_ER_PR_INVMSGFMT; /* The response contains only a header */ return 0; }
int omi_prc_unlc(omi_conn *cptr, char *xend, char *buff, char *bend) { GBLREF int omi_pid; GBLREF mlk_pvtblk *mlk_pvt_root; int rv; omi_si si; char *jid; mlk_pvtblk **prior; /* Client's $JOB */ OMI_SI_READ(&si, cptr->xptr); jid = cptr->xptr; cptr->xptr += si.value; /* Bounds checking */ if (cptr->xptr > xend) return -OMI_ER_PR_INVMSGFMT; /* Condition handler for DBMS operations */ ESTABLISH_RET(omi_dbms_ch,0); /* Loop through all the locks, unlocking ones that belong to this client */ for (prior = &mlk_pvt_root; *prior; ) { if (!(*prior)->granted || !(*prior)->nodptr || (*prior)->nodptr->owner != omi_pid) mlk_pvtblk_delete(prior); else if ((*prior)->nodptr->auxowner == (UINTPTR_T)cptr && si.value == (*prior)->value[(*prior)->total_length] && memcmp(&(*prior)->value[(*prior)->total_length+1], jid, si.value) == 0) { mlk_unlock(*prior); mlk_pvtblk_delete(prior); } else prior = &(*prior)->next; } REVERT; return 0; }
int omi_prc_conn(omi_conn *cptr, char *xend, char *buff, char *bend) { omi_si si, eightbit, chartran, ss_len, ext_cnt; omi_li li_min, li_max, ext; uns_short li_val; int len, i; char *bptr, *eptr; char *ag_name, *ag_pass, *s; bptr = buff; /* Version numbers */ OMI_SI_READ(&si, cptr->xptr); if (si.value != OMI_PROTO_MAJOR) return -OMI_ER_SE_VRSNOTSUPP; OMI_SI_WRIT(OMI_PROTO_MAJOR, bptr); /* XXX minor version numbers */ OMI_SI_READ(&si, cptr->xptr); OMI_SI_WRIT(OMI_PROTO_MINOR, bptr); /* Minimum and maximum parameters */ /* Data */ OMI_LI_READ(&li_min, cptr->xptr); if (OMI_MAX_DATA < li_min.value) { cptr->state = OMI_ST_CLOS; return -OMI_ER_SE_LENMIN; } OMI_LI_READ(&li_max, cptr->xptr); li_val = MIN(li_max.value, OMI_MAX_DATA); OMI_LI_WRIT(li_val, bptr); /* Subscript */ OMI_LI_READ(&li_min, cptr->xptr); if (OMI_MAX_SUBSCR < li_min.value) { cptr->state = OMI_ST_CLOS; return -OMI_ER_SE_LENMIN; } OMI_LI_READ(&li_max, cptr->xptr); li_val = MIN(li_max.value, OMI_MAX_SUBSCR); OMI_LI_WRIT(li_val, bptr); /* Reference */ OMI_LI_READ(&li_min, cptr->xptr); if (OMI_MAX_REF < li_min.value) { cptr->state = OMI_ST_CLOS; return -OMI_ER_SE_LENMIN; } OMI_LI_READ(&li_max, cptr->xptr); li_val = MIN(li_max.value, OMI_MAX_REF); OMI_LI_WRIT(li_val, bptr); /* Message */ OMI_LI_READ(&li_min, cptr->xptr); if (cptr->bsiz < li_min.value) { cptr->state = OMI_ST_CLOS; return -OMI_ER_SE_LENMIN; } OMI_LI_READ(&li_max, cptr->xptr); li_val = MIN(li_max.value, cptr->bsiz); OMI_LI_WRIT(li_val, bptr); /* Oustanding */ OMI_LI_READ(&li_min, cptr->xptr); if (1 < li_min.value) { cptr->state = OMI_ST_CLOS; return -OMI_ER_SE_LENMIN; } OMI_LI_READ(&li_max, cptr->xptr); li_val = MIN(li_max.value, 1); OMI_LI_WRIT(li_val, bptr); /* Other parameters */ OMI_SI_READ(&eightbit, cptr->xptr); OMI_SI_WRIT(eightbit.value, bptr); OMI_SI_READ(&chartran, cptr->xptr); OMI_SI_WRIT(chartran.value, bptr); /* Bounds checking */ if (cptr->xptr > xend || bptr >= bend) return -OMI_ER_PR_INVMSGFMT; /* Implementation ID (in) */ OMI_SI_READ(&ss_len, cptr->xptr); cptr->xptr += ss_len.value; /* Agent name (in) */ OMI_SI_READ(&ss_len, cptr->xptr); if ((ag_name = (char *) malloc(ss_len.value + 1)) == NULL) { OMI_DBG((omi_debug, "%s: memory allocation error (insufficient resources) while\n", SRVR_NAME)); OMI_DBG((omi_debug, "processing connect request from connection %d, %s.\n", cptr->stats.id, gtcm_hname(&cptr->stats.ai))); return -OMI_ER_DB_UNRECOVER; } assert(ss_len.value < MAX_USER_NAME && ss_len.value > 0); memcpy(ag_name, cptr->xptr, ss_len.value); ag_name[ss_len.value] = '\0'; strcpy(cptr->ag_name, ag_name); cptr->xptr += ss_len.value; /* Agent password (in) */ OMI_SI_READ(&ss_len, cptr->xptr); if ((ag_pass = (char *) malloc(ss_len.value + 1)) == NULL) { OMI_DBG((omi_debug, "%s: memory allocation error (insufficient resources) while\n", SRVR_NAME)); OMI_DBG((omi_debug, "processing connect request from connection %d, %s.\n", cptr->stats.id, gtcm_hname(&cptr->stats.ai))); return -OMI_ER_DB_UNRECOVER; } memcpy(ag_pass, cptr->xptr, ss_len.value); ag_pass[ss_len.value] = '\0'; cptr->xptr += ss_len.value; /* No support for authentication on SCO, Linux, Cygwin, or z/OS at the moment...*/ #if !(defined(SCO) || defined(__linux__) || defined(__CYGWIN__) || defined(__MVS__)) if (authenticate) /* verify password and user name */ { #ifdef SHADOWPW struct spwd *spass, *getspnam(); struct stat buf; #endif struct passwd *pass; char *pw, *syspw; /* lowercase agent name */ for(s = ag_name; *s; s++) if (ISUPPER_ASCII(*s)) *s = TOLOWER(*s); #ifdef SHADOWPW if (!Stat("/etc/shadow", &buf)) { if ((spass = getspnam(ag_name)) == NULL) { if (errno) { OMI_DBG((omi_debug, "%s: error opening /etc/shadow for input\n", SRVR_NAME, ag_name)); PERROR("/etc/shadow"); return -OMI_ER_DB_USERNOAUTH; } OMI_DBG((omi_debug, "%s: user %s not found in /etc/shadow\n", SRVR_NAME, ag_name)); return -OMI_ER_DB_USERNOAUTH; } syspw = spass->sp_pwdp; } else if ((pass = getpwnam(ag_name)) == NULL) { OMI_DBG((omi_debug, "%s: user %s not found in /etc/passwd\n", SRVR_NAME, ag_name)); return -OMI_ER_DB_USERNOAUTH; } else syspw = pass->pw_passwd; #else /* ndef SHADOWPW */ if ((pass = getpwnam(ag_name)) == NULL) { OMI_DBG((omi_debug, "%s: user %s not found in /etc/passwd\n", SRVR_NAME, ag_name)); return -OMI_ER_DB_USERNOAUTH; } else syspw = pass->pw_passwd; #endif /* SHADOWPW */ pw = (char *) crypt(ag_pass, syspw); if (strcmp(pw, syspw) != 0) { OMI_DBG((omi_debug, "%s: login attempt for user %s failed.\n", SRVR_NAME, ag_name)); return -OMI_ER_DB_USERNOAUTH; } } #endif /* SCO or linux or cygwin or z/OS */ /* Server name (in) */ OMI_SI_READ(&ss_len, cptr->xptr); cptr->xptr += ss_len.value; /* Implementation ID (out) */ len = SIZEOF(GTM_RELEASE_NAME) - 1; OMI_SI_WRIT(len, bptr); (void) memcpy(bptr, GTM_RELEASE_NAME, len); bptr += len; /* Server name (out) */ OMI_SI_WRIT(0, bptr); /* Server password (out) */ OMI_SI_WRIT(0, bptr); /* Bounds checking */ if (cptr->xptr > xend || bptr >= bend) return -OMI_ER_PR_INVMSGFMT; /* Extensions (in) -- count through them */ OMI_SI_READ(&ext_cnt, cptr->xptr); for (i = 0; i < ext_cnt.value; i++) { OMI_LI_READ(&ext, cptr->xptr); cptr->exts |= (1 << (ext.value - 1)); } /* Mask off extensions we don't support */ cptr->exts &= OMI_EXTENSIONS; /* Negotiate extension combinations */ if (cptr->exts & OMI_XTF_RC && cptr->exts & OMI_XTF_BUNCH) cptr->exts &= ~OMI_XTF_BUNCH; #ifdef GTCM_RC if (cptr->exts & OMI_XTF_RC) cptr->of = rc_oflow_alc(); #endif /* defined(GTCM_RC) */ /* Extensions (out) */ eptr = bptr; bptr += OMI_SI_SIZ; i = 0; if (cptr->exts & OMI_XTF_BUNCH) { OMI_LI_WRIT(OMI_XTN_BUNCH, bptr); i++; } if (cptr->exts & OMI_XTF_GGR) { OMI_LI_WRIT(OMI_XTN_GGR, bptr); i++; } if (cptr->exts & OMI_XTF_NEWOP) { OMI_LI_WRIT(OMI_XTN_NEWOP, bptr); i++; } if (cptr->exts & OMI_XTF_RC) { OMI_LI_WRIT(OMI_XTN_RC, bptr); i++; } /* Number of extensions */ OMI_SI_WRIT(i, eptr); /* Bounds checking */ if (cptr->xptr > xend || bptr >= bend) return -OMI_ER_PR_INVMSGFMT; /* Change the state of the connection */ cptr->state = OMI_ST_CONN; return (int)(bptr - buff); }
/* On OSF/1 (Digital Unix), pointers are 64 bits wide; the only exception to this is C programs for which one may * specify compiler and link editor options in order to use (and allocate) 32-bit pointers. However, since C is * the only exception and, in particular because the operating system does not support such an exception, the argv * array passed to the main program is an array of 64-bit pointers. Thus the C program needs to declare argv[] * as an array of 64-bit pointers and needs to do the same for any pointer it sets to an element of argv[]. */ int main(int argc, char_ptr_t argv[]) { omi_fd fd; char buff[OMI_BUFSIZ], *bptr, *xptr, *end, *chr; int cc, blen, bunches, i, n, len, buf[5], j, rdmr; omi_vi mlen, xlen; omi_li nx; omi_si hlen; omi_req_hdr rh; DCL_THREADGBL_ACCESS; GTM_THREADGBL_INIT; bunches = 0; if (argc == 3) { if (argv[1][0] != '-' || argv[1][1] != 'b' || argv[1][2] != '\0') { PRINTF("%s: bad command line arguments\n\t%s [ -b ] filename\n", argv[0], argv[0]); exit(-1); } else if (INV_FD_P((fd = open(argv[argc - 1], O_RDONLY)))) { PRINTF("%s: open(\"%s\"): %s\n", argv[0], argv[argc - 1], STRERROR(errno)); exit(-1); } } else if (argc == 2) { if (argv[1][0] == '-' && argv[1][1] == 'b' && argv[1][2] == '\0') fd = fileno(stdin); else if (INV_FD_P((fd = open(argv[argc - 1], O_RDONLY)))) { PRINTF("%s: open(\"%s\"): %s\n", argv[0], argv[argc - 1], STRERROR(errno)); exit(-1); } } else if (argc == 1) fd = fileno(stdin); else { PRINTF("%s: bad command line arguments\n\t%s [ -b ] [ filename ]\n", argv[0], argv[0]); exit(-1); } for (blen = 0, bptr = buff, n = 1, rdmr = 1; ; ) { if (rdmr) { cc = (int)(ARRAYTOP(buff) - &bptr[blen]); if ((cc = (int)(read(fd, &bptr[blen], cc))) < 0) { PRINTF("%s: read(): %s", argv[0], STRERROR(errno)); exit(-1); } else if (cc == 0) break; blen += cc; if (blen < OMI_VI_SIZ) { if (bptr != buff) { memmove(buff, bptr, blen); bptr = buff; } continue; } } xptr = bptr; OMI_VI_READ(&mlen, xptr); if (blen < mlen.value + 4) { if (bptr != buff) { memmove(buff, bptr, blen); bptr = buff; } rdmr = 1; continue; } rdmr = 0; PRINTF("Message %d, %ld bytes", n, (long)mlen.value); if (argc == 3 && bunches) { OMI_LI_READ(&nx, xptr); PRINTF(", %d transactions in bunch", nx.value); bptr += OMI_VI_SIZ + OMI_LI_SIZ; blen -= OMI_VI_SIZ + OMI_LI_SIZ; } else { nx.value = 1; xlen = mlen; } puts(""); for (i = 1; i <= nx.value; i++) { if (argc == 3 && bunches) { OMI_VI_READ(&xlen, xptr); } end = xptr + xlen.value; OMI_SI_READ(&hlen, xptr); OMI_LI_READ(&rh.op_class, xptr); OMI_SI_READ(&rh.op_type, xptr); OMI_LI_READ(&rh.user, xptr); OMI_LI_READ(&rh.group, xptr); OMI_LI_READ(&rh.seq, xptr); OMI_LI_READ(&rh.ref, xptr); if (rh.op_class.value == 1) { PRINTF(" %s (%ld bytes)", (omi_oprlist[rh.op_type.value]) ? omi_oprlist[rh.op_type.value] : "unknown",(long)xlen.value); if (argc == 3 && bunches) PRINTF(", transaction #%d in bunch", i); puts(""); } else PRINTF(" (%ld bytes)\n", (long)xlen.value); chr = (char *)buf; while (xptr < end) { fputc('\t', stdout); if ((len = (int)(end - xptr)) > 20) len = 20; memcpy(chr, xptr, len); xptr += len; for (j = len; j < 20; j++) chr[j] = '\0'; for (j = 0; j < 5; j++) PRINTF("%08x ", buf[j]); for (j = 0; j < 20; j++) { if (j >= len) chr[j] = ' '; else if (chr[j] < 32 || chr[j] > 126) chr[j] = '.'; } PRINTF("%20s\n", chr); } bptr += xlen.value + 4; blen -= xlen.value + 4; } if (argc == 3) bunches = 1; n++; } return 0; }
int omi_lkextnam( omi_conn *cptr, uns_short len, char *ref, char *data) { mlk_pvtblk *r; sgmnt_addrs *sa; gd_region *reg; mval ext, lck; char *ptr, *end; int subcnt, elen; omi_li li; omi_si si; bool rv; /* Pointers into the global reference */ ptr = ref; end = ref + len; /* Initialize part of the mval */ ext.mvtype = MV_STR; /* Refine the gd_addr given this environment */ OMI_LI_READ(&li, ptr); if (ptr + li.value > end) return -OMI_ER_PR_INVGLOBREF; ext.str.len = li.value; ext.str.addr = ptr; cptr->ga = zgbldir(&ext); ptr += li.value; elen = end - ptr; /* Refine the gd_addr given this name */ OMI_SI_READ(&si, ptr); if (!si.value || ptr + si.value > end) return -OMI_ER_PR_INVGLOBREF; lck.str.len = si.value; lck.str.addr = ptr; ptr += si.value; subcnt = 1; /* Refine the gd_addr given these subscripts */ while (ptr < end) { OMI_SI_READ(&si, ptr); if (!si.value || ptr + si.value > end) return -OMI_ER_PR_INVGLOBREF; ptr += si.value; subcnt++; } lck.mvtype = ext.mvtype = MV_STR; reg = mlk_region_lookup(&lck, cptr->ga); OMI_SI_READ(&si, data); r = (mlk_pvtblk *)malloc(sizeof(mlk_pvtblk) + elen + si.value); memset(r, 0, sizeof(mlk_pvtblk) - 1); r->translev = 1; r->subscript_cnt = subcnt; r->total_length = elen; memcpy(&r->value[0], lck.str.addr - 1, elen); r->value[elen++] = si.value; memcpy(&r->value[elen], data, si.value); r->region = reg; sa = &FILE_INFO(r->region)->s_addrs; r->ctlptr = (mlk_ctldata *)sa->lock_addrs[0]; if (!mlk_pvtblk_insert(r)) { if (r->value[r->total_length] == mlk_pvt_root->value[mlk_pvt_root->total_length] && !memcmp(&r->value[elen],&mlk_pvt_root->value[elen],r->value[r->total_length])) { free(r); return TRUE; } else return FALSE; } else if (r != mlk_pvt_root) return -OMI_ER_DB_UNRECOVER; return TRUE; }
int omi_gvextnam (omi_conn *cptr, uns_short len, char *ref) { bool was_null, is_null; mval v; char *ptr, *end, c[MAX_FBUFF + 1]; omi_li li; omi_si si; parse_blk pblk; int4 status; gd_segment *cur_seg, *last_seg; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; /* Pointers into the global reference */ ptr = ref; end = ref + len; /* Initialize part of the mval */ v.mvtype = MV_STR; /* Refine the gd_addr given this environment */ OMI_LI_READ(&li, ptr); if (ptr + li.value > end) return -OMI_ER_PR_INVGLOBREF; v.str.len = li.value; v.str.addr = ptr; cptr->ga = zgbldir(&v); memset(&pblk, 0, SIZEOF(pblk)); pblk.buffer = c; pblk.buff_size = MAX_FBUFF; pblk.def1_buf = DEF_GDR_EXT; pblk.def1_size = SIZEOF(DEF_GDR_EXT) - 1; status = parse_file(&v.str, &pblk); /* for all segments insert the full path in the segment fname */ cur_seg = cptr->ga->segments; last_seg = cur_seg + cptr->ga->n_segments; for( ; cur_seg < last_seg ; cur_seg++) { if ('/' != cur_seg->fname[0]) { /* doesn't contains full path ; specify full path */ memmove(&cur_seg->fname[0] + pblk.b_dir, cur_seg->fname, cur_seg->fname_len); memcpy(cur_seg->fname, pblk.l_dir, pblk.b_dir); cur_seg->fname_len += pblk.b_dir; } } ptr += li.value; /* Refine the gd_addr given this name */ OMI_SI_READ(&si, ptr); if (si.value <= 1 || *ptr != '^') return -OMI_ER_PR_INVGLOBREF; ptr++; si.value--; if (ptr + si.value > end) return -OMI_ER_PR_INVGLOBREF; v.str.len = si.value; v.str.addr = ptr; gd_header = cptr->ga; GV_BIND_NAME_AND_ROOT_SEARCH(cptr->ga, &v.str); ptr += si.value; /* Refine the gd_addr given these subscripts */ was_null = is_null = FALSE; while (ptr < end) { was_null |= is_null; OMI_SI_READ(&si, ptr); if (ptr + si.value > end) return -OMI_ER_PR_INVGLOBREF; v.mvtype = MV_STR; v.str.len = si.value; v.str.addr = ptr; is_null = (si.value == 0); mval2subsc(&v, gv_currkey); ptr += si.value; } TREF(gv_some_subsc_null) = was_null; /* if true, it indicates there is a null subscript (except the last subscript) in current key */ TREF(gv_last_subsc_null) = is_null; /* if true, it indicates that last subscript in current key is null */ if (was_null && NEVER == gv_cur_region->null_subs) return -OMI_ER_DB_INVGLOBREF; return 0; }
/* On OSF/1 (Digital Unix), pointers are 64 bits wide; the only exception to this is C programs for which one may * specify compiler and link editor options in order to use (and allocate) 32-bit pointers. However, since C is * the only exception and, in particular because the operating system does not support such an exception, the argv * array passed to the main program is an array of 64-bit pointers. Thus the C program needs to declare argv[] * as an array of 64-bit pointers and needs to do the same for any pointer it sets to an element of argv[]. */ int main(int argc, char_ptr_t argv[]) { #ifndef __linux__ #ifdef __osf__ #pragma pointer_size (save) #pragma pointer_size (long) #endif extern char *sys_errlist[]; #ifdef __osf__ #pragma pointer_size (restore) #endif #endif omi_fd fd; char buff[OMI_BUFSIZ], *bptr, *xptr, *end, *chr; int cc, blen, bunches, i, n, len, buf[5], j, rdmr; omi_vi mlen, xlen; omi_li nx; omi_si hlen; omi_req_hdr rh; bunches = 0; if (argc == 3) { if (argv[1][0] != '-' || argv[1][1] != 'b' || argv[1][2] != '\0') { printf("%s: bad command line arguments\n\t%s [ -b ] filename\n", argv[0], argv[0]); exit(-1); } else if (INV_FD_P((fd = open(argv[argc - 1], O_RDONLY)))) { printf("%s: open(\"%s\"): %s\n", argv[0], argv[argc - 1], sys_errlist[errno]); exit(-1); } } else if (argc == 2) { if (argv[1][0] == '-' && argv[1][1] == 'b' && argv[1][2] == '\0') fd = fileno(stdin); else if (INV_FD_P((fd = open(argv[argc - 1], O_RDONLY)))) { printf("%s: open(\"%s\"): %s\n", argv[0], argv[argc - 1], sys_errlist[errno]); exit(-1); } } else if (argc == 1) fd = fileno(stdin); else { printf("%s: bad command line arguments\n\t%s [ -b ] [ filename ]\n", argv[0], argv[0]); exit(-1); } for (blen = 0, bptr = buff, n = 1, rdmr = 1; ; ) { if (rdmr) { cc = &buff[sizeof(buff)] - &bptr[blen]; if ((cc = read(fd, &bptr[blen], cc)) < 0) { printf("%s: read(): %s", argv[0], sys_errlist[errno]); exit(-1); } else if (cc == 0) break; blen += cc; if (blen < OMI_VI_SIZ) { if (bptr != buff) { memmove(buff, bptr, blen); bptr = buff; } continue; } } xptr = bptr; OMI_VI_READ(&mlen, xptr); if (blen < mlen.value + 4) { if (bptr != buff) { memmove(buff, bptr, blen); bptr = buff; } rdmr = 1; continue; } rdmr = 0; printf("Message %d, %d bytes", n, mlen.value); if (argc == 3 && bunches) { OMI_LI_READ(&nx, xptr); printf(", %d transactions in bunch", nx.value); bptr += OMI_VI_SIZ + OMI_LI_SIZ; blen -= OMI_VI_SIZ + OMI_LI_SIZ; } else { nx.value = 1; xlen = mlen; } puts(""); for (i = 1; i <= nx.value; i++) { if (argc == 3 && bunches) { OMI_VI_READ(&xlen, xptr); } end = xptr + xlen.value; OMI_SI_READ(&hlen, xptr); OMI_LI_READ(&rh.op_class, xptr); OMI_SI_READ(&rh.op_type, xptr); OMI_LI_READ(&rh.user, xptr); OMI_LI_READ(&rh.group, xptr); OMI_LI_READ(&rh.seq, xptr); OMI_LI_READ(&rh.ref, xptr); if (rh.op_class.value == 1) { printf(" %s (%d bytes)", (omi_oprlist[rh.op_type.value]) ? omi_oprlist[rh.op_type.value] : "unknown",xlen.value); if (argc == 3 && bunches) printf(", transaction #%d in bunch", i); puts(""); } else printf(" (%d bytes)\n", xlen.value); chr = (char *)buf; while (xptr < end) { fputc('\t', stdout); if ((len = end - xptr) > 20) len = 20; memcpy(chr, xptr, len); xptr += len; for (j = len; j < 20; j++) chr[j] = '\0'; for (j = 0; j < 5; j++) printf("%08x ", buf[j]); for (j = 0; j < 20; j++) { if (j >= len) chr[j] = ' '; else if (chr[j] < 32 || chr[j] > 126) chr[j] = '.'; } printf("%20s\n", chr); } bptr += xlen.value + 4; blen -= xlen.value + 4; } if (argc == 3) bunches = 1; n++; } return 0; }