/* interp_list - * Interpret LIST output (in EPLF). */ void interp_list (char *filename) { FILE *in; #ifdef EPLF time_t diffgmt; /* number of seconds from local time to gmt */ int eplf = 0; #else int c; char buf[512]; #endif if ((in = Lfopen (filename, "r")) == NULL) { printf ("Couldn't open %s for reading\n", filename); return; } #ifdef EPLF diffgmt = dgmt (); while (fgets (acinput, sizeof (acinput) - 1, in)) { if (0 == eplf_readable (acinput, diffgmt)) printf ("%s\n", acinput); else eplf = 1; } if (eplf) printf ("Times are converted to local time.\n"); #else while ((c = fread (buf, 1, sizeof (buf), in))) fwrite (buf, 1, c, stdout); #endif Lfclose (in); } /* interp_list() */
/* sortupdt - Sorts update signals * * Takes the name of the update file as an * argument. Writes output to a new file * deletes the original, and renames * the new file, the original file name. * * Returns 0 if all OK * 1 if anything went wrong */ int sortupdt (char *filename) { int32_t dfilepos = 0; char ch; FILE *rf; FILE *wf; struct change_cmd chrec; int i = 0; int j; char newfile[SCPS_L_tmpnam]; char lastch; u_long lastofs; rf = Lfopen (filename, "r"); if (rf == NULL) return 1; while (get_ch_rec (&chrec, rf)) { /* printf("i: %d ch: %c ofs: %lu len: %hi\n", i, chrec.ch, chrec.foffset, chrec.len); */ allsignals[i].file_pos = dfilepos; allsignals[i].ch = chrec.ch; allsignals[i++].sig_fofs = chrec.foffset; if (i == MAXSIGNALS) goto sortupdtabort; if (chrec.ch != 'd') while (chrec.len--) { if (1 != fread (&ch, 1, 1, rf)) goto sortupdtabort; } /* while */ dfilepos = ftell (rf); } /* while */ if (i == 0) /* oops. No records. */ goto sortupdtabort; /* sort by the foffset field in the signal records */ qsort (allsignals, i, sizeof (struct update_sig), sortupdt_cmp); /* * for (j=0; j<i; j++) * printf("j: %d pos: %lu ofs: %lu\n", j, allsignals[j].file_pos, allsignals[j].sig_fofs); */ if (NULL == Ltmpnam (newfile)) goto sortcopyabort; wf = Lfopen (newfile, "w"); if (wf == NULL) goto sortupdtabort; /* copy the records to the new file in sorted order * While writing them, check to make sure they are * valid. If they aren't, abort. */ lastofs = 0; lastch = 0; for (j = 0; j < i; j++) { int32_t ltemp; short stemp; fseek (rf, allsignals[j].file_pos, SEEK_SET); if (0 == get_ch_rec (&chrec, rf)) goto sortcopyabort; if (lastofs) { if (chrec.foffset == lastofs && lastch != 'i') { /* duplicate offset numbers */ goto sortcopyabort; } } lastofs = chrec.foffset; lastch = chrec.ch; fwrite (&(chrec.ch), 1, 1, wf); ltemp = htonl (chrec.foffset); fwrite (<emp, 4, 1, wf); stemp = htons (chrec.len); fwrite (&stemp, 2, 1, wf); if (chrec.ch != 'd') { while (chrec.len--) { fread (&(chrec.ch), 1, 1, rf); fwrite (&(chrec.ch), 1, 1, wf); } } } /* while */ Lfclose (wf); Lfclose (rf); if (rename (newfile, filename)) { if (fcopy (newfile, filename)) return 1; remove (newfile); return 0; } return 0; sortcopyabort: if (wf) Lfclose (wf); sortupdtabort: if (rf) Lfclose (rf); return 1; } /* sortupdt */
int Linker::Link(int argctr, aCHAR* *pargv) { FILE *pFobj, *pFtarg; int filei, i, j, count, pos; int fpos_eoa; aBYTE ibuf[CL_HEAD_LENGTH+4]; aBYTE checksum, curbyte; bool is_system = false; #if defined(_WIN32) DWORD v = ::GetVersion(); g_osver = v < 0x80000000 ? WNT : W95; #else g_osver = OtherOS; #endif try { // locking(); // get the registration status and info output(aS("Linking: %s"), pargv[0]); if (Lstrstr(pargv[0], aS("alis.xpl")) != NULL || Lstrstr(pargv[0], aS("acmp.xpl")) != NULL || Lstrstr(pargv[0], aS("aidl.xpl")) != NULL || Lstrstr(pargv[0], aS("axrf.xpl")) != NULL ) { is_system = true; } // Open output .xpl file if (NULL == (pFtarg = Lfopen(pargv[0], aS("w+b")))) abort_linker(aS("Error: Cannot open xpl file %s"), pargv[0]); // make two passes through files - first one builds // complete atom table - second pass constructs new file // header and atom table then writes out clauses // pass 0 - initialise if (NULL == (GAtomTable = (G_ATOM*) new G_ATOM[eMaxAtoms] )) abort_linker(aS("Insufficient memory for global atom table")); //for(i = 0; i < eMaxAtoms; ++i) // GAtomTable[i].name = NULL; if (NULL == (LAtomTable = (L_ATOM*) new L_ATOM[eMaxAtoms] )) abort_linker(aS("Insufficient memory for local atom table")); for(i = 0; i < eMaxAtoms; ++i) LAtomTable[i] = NULL; // pass1 for (filei = 1; filei < argctr; ++filei) { output(aS("Opening: '%s'"), pargv[filei]); if (NULL == (pFobj = Lasys_fopen(pargv[filei], aS("rb"), aS("abin")))) abort_linker(aS("Error: Cannot open plm file '%s'"), pargv[filei]); else { //output(aS("Reading Atom Table: %s"), pargv[filei]); read_g_atoms(pFobj, filei); fclose(pFobj); } } // now read through global atom table setting index field // to the index of the atom as it will be when the table // is written out count = 0; for(i = 0; i < eMaxAtoms; ++i) if (GAtomTable[i].name) { GAtomTable[i].index = count; ++count; } for (i = 0; i < CL_HEAD_LENGTH+4; i++) ibuf[i] = 0; /* Header bytes 0 - ff indicating a load module 1 - xpl/plm flag + unicode flag + large + longcode 2 - version 3 - build 4 - check sum of remaining header stuff + atom table 5 - 0, 1, 2 for professional or personal or evaluation edition 6 - platform id based on linker - 1 - Win32 7-? - serial number product code (ex. APX) - serial number platform code (ex. PC) - serial number sequence ID, as a long (ex. 93309) */ // write header ibuf[0] = 0xFF; // the tag #ifdef _UNICODE ibuf[1] = 0x72; // .xpl + Unicode + large + long code #else ibuf[1] = 0x22; // signifying .xpl file + large #endif ibuf[2] = VERSION_NUMBER; // set module bit ibuf[3] = BUILD_NUMBER; // oldest compiler version supported #ifdef DISTVER #ifdef BUG_LINK fprintf(lout, "** Starting Initialization\n"); fflush(lout); #endif ibuf[8] = 0; ibuf[9] = 0; ibuf[10] = 0; ibuf[11] = 0; ibuf[12] = 0; ibuf[13] = 0; ibuf[14] = 0; ibuf[15] = 0; for (i = 16, j=0; i < CL_HEAD_LENGTH; i++, j++) ibuf[i] = ibuf[8+j] ^ (aBYTE)i; #endif // DISTVER // fill out header and first four bytes of atom table length with 0s ucFWRITE(ibuf, 1, CL_HEAD_LENGTH+4, pFtarg); count = 0; for(i = 0; i < eMaxAtoms; ++i) // now write the atom table { if (GAtomTable[i].name) { aCHAR *nptr = GAtomTable[i].name; write_wstring(GAtomTable[i].name, pFtarg); ++count; } } pos = (int) ftell(pFtarg); // currrent pos fpos_eoa = pos; // end of atom table file pos fseek(pFtarg, CL_HEAD_LENGTH, SEEK_SET); // posn for atom table length pos = pos - (CL_HEAD_LENGTH + 4); // length of table //printf("pos = 0x%x\n",pos); ray write_int32(pos, pFtarg); // write it out // write_int16(pos, pFtarg); // write it out #ifdef BUG_LINK fprintf(lout, "** Atom Table Done\n"); fflush(lout); #endif // compute check sum, starting with byte #5 and ending before fpos_eoa. fseek(pFtarg, 5, SEEK_SET); // write it in byte #4. checksum = 0xaa; for (i=5; i<fpos_eoa; i++) { fread(&curbyte, 1, 1, pFtarg); curbyte += (aBYTE)i; checksum ^= curbyte; } fseek(pFtarg, 4, SEEK_SET); ucFWRITE(&checksum, 1, 1, pFtarg); #ifdef BUG_LINK fprintf(lout, "** Check Sum Done\n"); fflush(lout); #endif // Back to the end of the atom table to continue the real work. fseek(pFtarg, (long)(pos+CL_HEAD_LENGTH+4), SEEK_SET); for (filei = 1; filei < argctr; ++filei) { if (NULL == (pFobj = Lasys_fopen(pargv[filei], aS("rb"), aS("abin")))) abort_linker(aS("Warning: Cannot open PLM file %s"), pargv[filei]); else { //output(aS("Reading Code Segments: %s"), pargv[filei]); read_code_segs(pFobj, pFtarg, filei); fclose(pFobj); } } #ifdef BUG_LINK fprintf(lout, "** Code Segments Done\n"); fflush(lout); #endif // originally added to catch a bug with binary files and VMS, // but is now used to determine end of code, so leave in. ibuf[0] = 0; for (i=0; i<4; i++) ucFWRITE(ibuf, 1, 1, pFtarg); // write file names at end of file, so that ensure_loaded, if // used, can check to see if a given file was loaded as part // of an .xpl file, end with zeroes as above. for (filei = 1; filei < argctr; ++filei) { write_wstring(pargv[filei], pFtarg); } // originally added to catch a bug with binary files and VMS, // but is now used to determine end of file as well, so leave in. ibuf[0] = 0; for (i=0; i<4; i++) ucFWRITE(ibuf, 1, 1, pFtarg); fclose(pFtarg); for(i = 1, count = 0; i < eMaxAtoms; ++i) { if (GAtomTable[i].name) ++count; } //output(aS("%d Global Atoms"), count); output(aS("Link Done")); } catch (ErrCode) { #ifdef BUG_LINK fprintf(lout, "** Returning NOTOK 1\n"); fflush(lout); #endif #ifdef BUG_LINK fclose(lout); #endif return NOTOK; } catch (...) { #ifdef BUG_LINK fprintf(lout, "** Returning NOTOK 2\n"); fflush(lout); #endif #ifdef BUG_LINK fclose(lout); #endif output(aS("\nUnrecognized system error")); return NOTOK; } #ifdef BUG_LINK fprintf(lout, "** Returning OK\n"); fflush(lout); #endif #ifdef BUG_LINK fclose(lout); #endif return OK; }