/* registers a module, register_f= module register functions * returns <0 on error, 0 on success */ static int register_module(module_exports_t* e, char* path, void* handle) { int ret, i; struct sr_module* mod; char defmod[64]; int n = 0; ret=-1; /* add module to the list */ if ((mod=pkg_malloc(sizeof(struct sr_module)))==0){ LM_ERR("memory allocation failure\n"); ret=E_OUT_OF_MEM; goto error; } memset(mod, 0, sizeof(struct sr_module)); mod->path=path; mod->handle=handle; /* copy and convert fields */ mod->exports.name = e->name; mod->exports.dlflags = e->dlflags; if(e->cmds) { for (n=0; e->cmds[n].name; n++); } mod->exports.cmds = pkg_malloc(sizeof(ksr_cmd_export_t)*(n+1)); memset(mod->exports.cmds, 0, sizeof(ksr_cmd_export_t)*(n+1)); for (i=0; i < n; i++) { mod->exports.cmds[i].name = e->cmds[i].name; mod->exports.cmds[i].function = e->cmds[i].function; mod->exports.cmds[i].param_no = e->cmds[i].param_no; mod->exports.cmds[i].fixup = e->cmds[i].fixup; mod->exports.cmds[i].free_fixup = e->cmds[i].free_fixup; mod->exports.cmds[i].flags = e->cmds[i].flags; mod->exports.cmds[i].fixup_flags = 0; mod->exports.cmds[i].module_exports = mod; /* fill known free fixups */ if (mod->exports.cmds[i].fixup && mod->exports.cmds[i].free_fixup == 0) { mod->exports.cmds[i].free_fixup = get_fixup_free(mod->exports.cmds[i].fixup); } } mod->exports.params = e->params; mod->exports.rpc_methods = e->rpc_methods; mod->exports.pv_items = e->pv_items; mod->exports.response_f = e->response_f; mod->exports.init_mod_f = e->init_mod_f; mod->exports.init_child_f = e->init_child_f; mod->exports.destroy_mod_f = e->destroy_mod_f; if (mod->exports.pv_items) { /* register module pseudo-variables for kamailio modules */ LM_DBG("register PV from: %s\n", mod->exports.name); if (register_pvars_mod(mod->exports.name, mod->exports.pv_items)!=0) { LM_ERR("failed to register pseudo-variables for module %s (%s)\n", mod->exports.name, path); ret = E_UNSPEC; goto error; } } if (mod->exports.rpc_methods){ /* register rpcs for ser modules */ i=rpc_register_array(mod->exports.rpc_methods); if (i<0){ LM_ERR("failed to register RPCs for module %s (%s)\n", mod->exports.name, path); ret = E_UNSPEC; goto error; }else if (i>0){ LM_ERR("%d duplicate RPCs name detected while registering RPCs" " declared in module %s (%s)\n", i, mod->exports.name, path); ret = E_UNSPEC; goto error; } /* i==0 => success */ } /* add cfg define for each module: MOD_modulename */ if(strlen(mod->exports.name)>=60) { LM_ERR("too long module name: %s\n", mod->exports.name); goto error; } strcpy(defmod, "MOD_"); strcat(defmod, mod->exports.name); pp_define_set_type(0); if(pp_define(strlen(defmod), defmod)<0) { LM_ERR("unable to set cfg define for module: %s\n", mod->exports.name); goto error; } /* link module in the list */ mod->next=modules; modules=mod; return 0; error: if (mod) pkg_free(mod); return ret; }
int preprocess(int ln, char *line, int *mode) { int i; char *p; p = line; skip_white_space(&p); if (*p == '#') { ++p; // else if (strncmp(p, "else", 4) == 0) { // toggle mode if (*mode == XPP_OUTP) { *mode = XPP_SKIP; } else { *mode = XPP_OUTP; } return XPP_SKIP; } // endif if (strncmp(p, "endif", 5) == 0) { *mode = XPP_OUTP; return XPP_SKIP; } if (*mode == XPP_OUTP) { // directives only processed in output mode // comment if (strncmp(p, "//", 2) == 0) { return XPP_SKIP; } // include if (strncmp(p, "include ", 8) == 0) { pp_include(p + 7); return XPP_SKIP; } // define if (strncmp(p, "define ", 7) == 0) { pp_define(p + 6, false); return XPP_SKIP; } // defword if (strncmp(p, "defword ", 8) == 0) { pp_define(p + 7, true); return XPP_SKIP; } // undef if (strncmp(p, "undef ", 6) == 0) { pp_undef(p + 5); return XPP_SKIP; } // ifdef if (strncmp(p, "ifdef ", 6) == 0) { *mode = pp_ifdef(p + 5); return XPP_SKIP; } // ifndef if (strncmp(p, "ifndef ", 7) == 0) { *mode = pp_ifndef(p + 6); return XPP_SKIP; } } } // end if (*p == '#') // text replacements if (*mode == XPP_OUTP) { for (i = m_symbol_len - 1; i >= 0 ; --i) { if (strreplg(line, XPP_MAX_LINE_LEN, m_symbol[i].id, m_symbol[i].val, m_symbol[i].ww) < 0) { printf("Warning: missed a replacement on line %i: \"%s\" -> \"%s\"\n", ln, m_symbol[i].id, m_symbol[i].val); } } } return *mode; }
int main(int argc,char *argv[]) { int er=1,i; signed char *s=NULL; char *tmpp; int mifiles = 5; int nifiles = 0; int verbose = 0; int oldfile = 0; int no_link = 0; char **ifiles; char *ofile; char *efile; char *lfile; char *ifile; char old_e[MAXLINE]; char old_l[MAXLINE]; char old_o[MAXLINE]; tim1=time(NULL); ncmos=0; n65816=0; cmosfl=1; w65816=0; /* default: 6502 only */ altppchar = '#' ; /* i.e., NO alternate char */ if((tmpp = strrchr(argv[0],'/'))) { tmpp++; } else { tmpp = argv[0]; } if( (!strcmp(tmpp,"xa65816")) || (!strcmp(tmpp,"XA65816")) || (!strcmp(tmpp,"xa816")) || (!strcmp(tmpp,"XA816")) ) { w65816 = 1; /* allow 65816 per default */ } /* default output charset for strings in quotes */ set_charset("ASCII"); ifiles = malloc(mifiles*sizeof(char*)); afile = alloc_file(); if (argc <= 1) { usage(w65816, stderr); exit(1); } if (strstr(argv[1], "--help")) { usage(w65816, stdout); exit(0); } if (strstr(argv[1], "--version")) { version(programname, progversion, authors, copyright); exit(0); } ofile="a.o65"; efile=NULL; lfile=NULL; if(pp_init()) { logout("fatal: pp: no memory!"); return 1; } if(b_init()) { logout("fatal: b: no memory!"); return 1; } if(l_init()) { logout("fatal: l: no memory!"); return 1; } i=1; while(i<argc) { if(argv[i][0]=='-') { switch(argv[i][1]) { case 'p': /* intentionally not allowing an argument to follow with a space to avoid - being seen as the alternate preprocessor char! */ if (argv[i][2] == '\0') { fprintf(stderr, "-p requires a character argument\n"); exit(1); } if (argv[i][2] == '#') fprintf(stderr, "using -p# is evidence of stupidity\n"); altppchar = argv[i][2]; if (argv[i][3] != '\0') fprintf(stderr, "warning: extra characters to -p ignored\n"); break; case 'M': masm = 1; /* MASM compatibility mode */ break; case 'O': /* output charset */ { char *name = NULL; if (argv[i][2] == 0) { name = argv[++i]; } else { name = argv[i]+2; } if (set_charset(name) < 0) { fprintf(stderr, "Output charset name '%s' unknown - ignoring! (check case?)\n", name); } } break; case 'A': /* make text segment start so that text relocation is not necessary when _file_ starts at adr */ romable = 2; if(argv[i][2]==0) romaddr = atoi(argv[++i]); else romaddr = atoi(argv[i]+2); break; case 'G': noglob = 1; break; case 'L': /* define global label */ if(argv[i][2]) lg_set(argv[i]+2); break; case 'r': crossref = 1; break; case 'R': relmode = 1; break; case 'D': s = (signed char*)strstr(argv[i]+2,"="); if(s) *s = ' '; pp_define(argv[i]+2); break; case 'c': no_link = 1; fmode |= FM_OBJ; break; case 'v': verbose = 1; break; case 'C': cmosfl = 0; break; case 'W': w65816 = 0; break; case 'w': w65816 = 1; break; case 'B': showblk = 1; break; case 'x': /* old filename behaviour */ oldfile = 1; fprintf(stderr, "Warning: -x is now deprecated and may disappear in future versions!\n"); break; case 'I': if(argv[i][2]==0) { reg_include(argv[++i]); } else { reg_include(argv[i]+2); } break; case 'o': if(argv[i][2]==0) { ofile=argv[++i]; } else { ofile=argv[i]+2; } break; case 'l': if(argv[i][2]==0) { lfile=argv[++i]; } else { lfile=argv[i]+2; } break; case 'e': if(argv[i][2]==0) { efile=argv[++i]; } else { efile=argv[i]+2; } break; case 'b': /* set segment base addresses */ switch(argv[i][2]) { case 't': if(argv[i][3]==0) tbase = atoi(argv[++i]); else tbase = atoi(argv[i]+3); break; case 'd': if(argv[i][3]==0) dbase = atoi(argv[++i]); else dbase = atoi(argv[i]+3); break; case 'b': if(argv[i][3]==0) bbase = atoi(argv[++i]); else bbase = atoi(argv[i]+3); break; case 'z': if(argv[i][3]==0) zbase = atoi(argv[++i]); else zbase = atoi(argv[i]+3); break; default: fprintf(stderr,"unknown segment type '%c' - ignoring!\n", argv[i][2]); break; } break; case 0: fprintf(stderr, "Single dash '-' on command line - ignoring!\n"); break; default: fprintf(stderr, "Unknown option '%c' - ignoring!\n",argv[i][1]); break; } } else { /* no option -> filename */ ifiles[nifiles++] = argv[i]; if(nifiles>=mifiles) { mifiles += 5; ifiles=realloc(ifiles, mifiles*sizeof(char*)); if(!ifiles) { fprintf(stderr, "Oops: couldn't alloc enough mem for filelist table..!\n"); exit(1); } } } i++; } if(!nifiles) { fprintf(stderr, "No input files given!\n"); exit(0); } if(oldfile) { strcpy(old_e, ifiles[0]); strcpy(old_o, ifiles[0]); strcpy(old_l, ifiles[0]); if(setfext(old_e,".err")==0) efile = old_e; if(setfext(old_o,".obj")==0) ofile = old_o; if(setfext(old_l,".lab")==0) lfile = old_l; } fplab= lfile ? xfopen(lfile,"w") : NULL; fperr= efile ? xfopen(efile,"w") : NULL; if(!strcmp(ofile,"-")) { ofile=NULL; fpout = stdout; } else { fpout= xfopen(ofile,"wb"); } if(!fpout) { fprintf(stderr, "Couldn't open output file!\n"); exit(1); } if(verbose) fprintf(stderr, "%s\n",copyright); if(1 /*!m_init()*/) { if(1 /*!b_init()*/) { if(1 /*!l_init()*/) { /*if(!pp_init())*/ { if(!x_init()) { if(fperr) fprintf(fperr,"%s\n",copyright); if(verbose) logout(ctime(&tim1)); /* Pass 1 */ pc[SEG_ABS]= 0; /* abs addressing */ seg_start(fmode, tbase, dbase, bbase, zbase, 0, relmode); if(relmode) { r_mode(RMODE_RELOC); segment = SEG_TEXT; } else { r_mode(RMODE_ABS); } nolink = no_link; for (i=0; i<nifiles; i++) { ifile = ifiles[i]; sprintf(out,"xAss65: Pass 1: %s\n",ifile); if(verbose) logout(out); er=pp_open(ifile); puttmp(0); puttmp(T_FILE); puttmp(0); puttmp(0); puttmps((signed char*)&ifile, sizeof(filep->fname)); if(!er) { er=pass1(); pp_close(); } else { sprintf(out, "Couldn't open source file '%s'!\n", ifile); logout(out); } } if((er=b_depth())) { sprintf(out,"Still %d blocks open at end of file!\n",er); logout(out); } if(tbase & (align-1)) { sprintf(out,"Warning: text segment ($%04x) start address doesn't align to %d!\n", tbase, align); logout(out); } if(dbase & (align-1)) { sprintf(out,"Warning: data segment ($%04x) start address doesn't align to %d!\n", dbase, align); logout(out); } if(bbase & (align-1)) { sprintf(out,"Warning: bss segment ($%04x) start address doesn't align to %d!\n", bbase, align); logout(out); } if(zbase & (align-1)) { sprintf(out,"Warning: zero segment ($%04x) start address doesn't align to %d!\n", zbase, align); logout(out); } if (n65816>0) fmode |= 0x8000; switch(align) { case 1: break; case 2: fmode |= 1; break; case 4: fmode |= 2; break; case 256: fmode |=3; break; } if((!er) && relmode) h_write(fpout, fmode, tlen, dlen, blen, zlen, 0); if(!er) { if(verbose) logout("xAss65: Pass 2:\n"); seg_pass2(); if(!relmode) { r_mode(RMODE_ABS); } else { r_mode(RMODE_RELOC); segment = SEG_TEXT; } er=pass2(); } if(fplab) printllist(fplab); tim2=time(NULL); if(verbose) printstat(); if((!er) && relmode) seg_end(fpout); /* write reloc/label info */ if(fperr) fclose(fperr); if(fplab) fclose(fplab); if(fpout) fclose(fpout); } else { logout("fatal: x: no memory!\n"); } pp_end(); /* } else { logout("fatal: pp: no memory!");*/ } } else { logout("fatal: l: no memory!\n"); } } else { logout("fatal: b: no memory!\n"); } /*m_exit();*/ } else { logout("Not enough memory available!\n"); } if(ner || er) { fprintf(stderr, "Break after %d error%c\n",ner,ner?'s':0); /*unlink();*/ if(ofile) { unlink(ofile); } } free(ifiles); return( (er || ner) ? 1 : 0 ); }
/* registers a module, register_f= module register functions * returns <0 on error, 0 on success */ static int register_module(unsigned ver, union module_exports_u* e, char* path, void* handle) { int ret, i; struct sr_module* mod; char defmod[64]; ret=-1; /* add module to the list */ if ((mod=pkg_malloc(sizeof(struct sr_module)))==0){ LM_ERR("memory allocation failure\n"); ret=E_OUT_OF_MEM; goto error; } memset(mod,0, sizeof(struct sr_module)); mod->path=path; mod->handle=handle; mod->orig_mod_interface_ver=ver; /* convert exports to sr31 format */ if (ver == 0) { /* ser <= 3.0 */ mod->exports.name = e->v0.name; if (e->v0.cmds) { mod->exports.cmds = sr_cmd_exports_convert(ver, e->v0.cmds, mod); if (mod->exports.cmds == 0) { LM_ERR("failed to convert module command exports to 3.1 format" " for module \"%s\" (%s), interface version %d\n", mod->exports.name, mod->path, ver); ret = E_UNSPEC; goto error; } } mod->exports.params = e->v0.params; mod->exports.init_f = e->v0.init_f; mod->exports.response_f = e->v0.response_f; mod->exports.destroy_f = e->v0.destroy_f; mod->exports.onbreak_f = e->v0.onbreak_f; mod->exports.init_child_f = e->v0.init_child_f; mod->exports.dlflags = 0; /* not used in ser <= 3.0 */ mod->exports.rpc_methods = e->v0.rpc_methods; /* the rest are 0, not used in ser */ } else if (ver == 1) { /* kamailio <= 3.0 */ mod->exports.name = e->v1.name; if (e->v1.cmds) { mod->exports.cmds = sr_cmd_exports_convert(ver, e->v1.cmds, mod); if (mod->exports.cmds == 0) { LM_ERR("failed to convert module command exports to 3.1 format" " for module \"%s\" (%s), interface version %d\n", mod->exports.name, mod->path, ver); ret = E_UNSPEC; goto error; } } mod->exports.params = e->v1.params; mod->exports.init_f = e->v1.init_f; mod->exports.response_f = e->v1.response_f; mod->exports.destroy_f = e->v1.destroy_f; mod->exports.onbreak_f = 0; /* not used in k <= 3.0 */ mod->exports.init_child_f = e->v1.init_child_f; mod->exports.dlflags = e->v1.dlflags; mod->exports.rpc_methods = 0; /* not used in k <= 3.0 */ mod->exports.stats = e->v1.stats; mod->exports.mi_cmds = e->v1.mi_cmds; mod->exports.items = e->v1.items; mod->exports.procs = e->v1.procs; } else { LM_ERR("unsupported module interface version %d\n", ver); ret = E_UNSPEC; goto error; } if (mod->exports.items) { /* register module pseudo-variables for kamailio modules */ LM_DBG("register PV from: %s\n", mod->exports.name); if (register_pvars_mod(mod->exports.name, mod->exports.items)!=0) { LM_ERR("failed to register pseudo-variables for module %s (%s)\n", mod->exports.name, path); ret = E_UNSPEC; goto error; } } if (mod->exports.rpc_methods){ /* register rpcs for ser modules */ i=rpc_register_array(mod->exports.rpc_methods); if (i<0){ LM_ERR("failed to register RPCs for module %s (%s)\n", mod->exports.name, path); ret = E_UNSPEC; goto error; }else if (i>0){ LM_ERR("%d duplicate RPCs name detected while registering RPCs" " declared in module %s (%s)\n", i, mod->exports.name, path); ret = E_UNSPEC; goto error; } /* i==0 => success */ } /* add cfg define for each module: MOD_modulename */ if(strlen(mod->exports.name)>=60) { LM_ERR("too long module name: %s\n", mod->exports.name); goto error; } strcpy(defmod, "MOD_"); strcat(defmod, mod->exports.name); pp_define_set_type(0); if(pp_define(strlen(defmod), defmod)<0) { LM_ERR("unable to set cfg define for module: %s\n", mod->exports.name); goto error; } /* link module in the list */ mod->next=modules; modules=mod; return 0; error: if (mod) pkg_free(mod); return ret; }