File:  [Coherent Logic Development] / freem / src / mlib.c
Revision 1.6: download - view: text, annotated - select for diffs
Sun Apr 13 04:22:43 2025 UTC (3 months, 2 weeks ago) by snw
Branches: MAIN
CVS tags: HEAD
Fix snprintf calls

    1: /*
    2:  *   $Id: mlib.c,v 1.6 2025/04/13 04:22:43 snw Exp $
    3:  *    Function prototypes, structs, and macros for FreeM
    4:  *    binding library
    5:  *
    6:  *  
    7:  *   Author: Serena Willis <snw@coherent-logic.com>
    8:  *    Copyright (C) 1998 MUG Deutschland
    9:  *    Copyright (C) 2020, 2025 Coherent Logic Development LLC
   10:  *
   11:  *
   12:  *   This file is part of FreeM.
   13:  *
   14:  *   FreeM is free software: you can redistribute it and/or modify
   15:  *   it under the terms of the GNU Affero Public License as published by
   16:  *   the Free Software Foundation, either version 3 of the License, or
   17:  *   (at your option) any later version.
   18:  *
   19:  *   FreeM is distributed in the hope that it will be useful,
   20:  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   21:  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   22:  *   GNU Affero Public License for more details.
   23:  *
   24:  *   You should have received a copy of the GNU Affero Public License
   25:  *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
   26:  *
   27:  *   $Log: mlib.c,v $
   28:  *   Revision 1.6  2025/04/13 04:22:43  snw
   29:  *   Fix snprintf calls
   30:  *
   31:  *   Revision 1.5  2025/04/10 01:24:38  snw
   32:  *   Remove C++ style comments
   33:  *
   34:  *   Revision 1.4  2025/03/24 04:13:11  snw
   35:  *   Replace action macro dat with fra_dat to avoid symbol conflict on OS/2
   36:  *
   37:  *   Revision 1.3  2025/03/09 19:50:47  snw
   38:  *   Second phase of REUSE compliance and header reformat
   39:  *
   40:  *
   41:  * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
   42:  * SPDX-License-Identifier: AGPL-3.0-or-later
   43:  **/
   44: 
   45: #include <stdlib.h>
   46: 
   47: #include "mpsdef.h"
   48: #include "freem.h"
   49: #include "init.h"
   50: #include "transact.h"
   51: #include "version.h"
   52: 
   53: #include <stdio.h>
   54: #include <ctype.h>
   55: #include <string.h>
   56: #include <errno.h>
   57: 
   58: /* the following function prototypes are not in freem.h, as they are intended to be
   59:  * private and internal to mlib.c
   60:  */
   61: void mref2str(freem_ref_t *ref, char *key);
   62: void freem_release_io(void);
   63: void freem_return_io(void);
   64: 
   65: extern int xecline(int typ);
   66: 
   67: void mref2str(freem_ref_t *ref, char *key)
   68: {
   69:     register int i;
   70: 
   71:     for (i = 0; i < 256; i++) key[i] = NUL;
   72: 
   73:     switch (ref->reftype) {
   74: 
   75:         case MREF_RT_LOCAL: /* do nothing for locals, as they have no sigil */
   76:             break;
   77: 
   78:         case MREF_RT_GLOBAL:
   79:             strcat (key, "^");
   80:             break;
   81: 
   82:         case MREF_RT_SSVN:
   83:             strcat (key, "^$");
   84:             break;
   85: 
   86:     }
   87: 
   88:     if (ref->subscript_count > 0) {
   89:         strcat (key, ref->name);
   90:         strcat (key, "\202");
   91: 
   92:     	for (i = 0; i < ref->subscript_count; i++) {
   93:             strcat (key, ref->subscripts[i]);
   94:     		
   95:             if (i < ref->subscript_count - 1) strcat (key, "\202");
   96:     	}
   97:     }
   98:     else {
   99:         strcat (key, ref->name);
  100:     }
  101: 
  102:     /* ends with EOL */
  103:     strncat (key, "\201", 2);
  104: 
  105: }
  106: 
  107: pid_t freem_init(char *environment_name, char *namespace_name)
  108: {
  109:     int ierr_sav;
  110:     int errno_sav;
  111: 
  112:     libflag = TRUE;
  113:     noclear = TRUE;
  114:     frm_filter = TRUE;
  115:     direct_mode = FALSE;
  116:     
  117:     errno = 0;
  118:     
  119:     strcpy (shm_env, environment_name);
  120:     snprintf (config_file, sizeof (config_file) - 1, "%s/freem/%s/freem.conf", SYSCONFDIR, shm_env);
  121:     
  122:     init (namespace_name);
  123:     ierr_sav = ierr;
  124:     errno_sav = errno;
  125:     
  126:     freem_release_io ();
  127: 
  128: 
  129:     if (ierr_sav > OK || errno_sav != 0) {
  130:         return -1;
  131:     }
  132:     else {
  133:         return pid;
  134:     }
  135: }
  136: 
  137: short freem_version(char *result)
  138: {
  139:     strncpy (result, FREEM_VERSION_ID, 255);
  140: 
  141:     return OK;
  142: }
  143: 
  144: short freem_get(freem_ref_t *ref) 
  145: {
  146:     char key[256];
  147:     char result[256];
  148: 
  149:     freem_return_io ();
  150: 
  151:     /* set up the EOL-delimited string */
  152:     mref2str (ref, key);
  153: 
  154:     switch (ref->reftype) {
  155:     	
  156:     	case MREF_RT_LOCAL:
  157:             /* call into the symbol table to get the local var */
  158:             symtab (get_sym, key, result);
  159:             ref->status = merr ();
  160:             break;
  161:     	
  162:     	case MREF_RT_GLOBAL:
  163:             /* call into the FreeM global handler; result in &result */
  164:             global (get_sym, key, result);
  165:             ref->status = merr ();
  166:             break;
  167: 
  168:     	case MREF_RT_SSVN:
  169:             /* call into the SSVN code */
  170:             ssvn (get_sym, key, result);
  171:             ref->status = merr ();
  172:             break;
  173: 
  174:     }
  175:     
  176:     stcnv_m2c (result);
  177: 
  178:     strncpy (ref->value, result, sizeof (ref->value));
  179: 
  180:     freem_release_io ();
  181:     
  182:     return ref->status;
  183: }
  184: 
  185: short freem_set(freem_ref_t *ref) 
  186: {
  187:     char key[256];
  188:     char data[256];
  189: 
  190:     freem_return_io ();
  191: 
  192:     mref2str (ref, key);
  193: 
  194:     snprintf (data, sizeof (data) - 1, "%s\201", ref->value);
  195: 
  196:     switch (ref->reftype) {
  197: 
  198:         case MREF_RT_LOCAL:
  199:             /* call into the symbol table to set the local var */
  200:             symtab (set_sym, key, data);
  201:             ref->status = merr ();
  202:             break;
  203:     	
  204:     	case MREF_RT_GLOBAL:
  205:             /* call into the FreeM global handler; data in &data */
  206:             global (set_sym, key, data);
  207:             ref->status = merr ();
  208:             break;
  209: 
  210:     	case MREF_RT_SSVN:
  211:             /* call into the SSVN code */
  212:             ssvn (set_sym, key, data);
  213:             ref->status = merr ();
  214:             break;
  215: 
  216:     }
  217: 
  218:     freem_release_io ();
  219: 
  220: 
  221:     return ref->status;
  222: }
  223: 
  224: short freem_kill(freem_ref_t *ref) 
  225: {
  226:     char key[256];
  227:     char result[256];
  228: 
  229:     mref2str (ref, key);
  230: 
  231:     freem_return_io ();
  232: 
  233:     switch (ref->reftype) {
  234:     	
  235:     	case MREF_RT_LOCAL:
  236:             /* call into the symbol table to kill the local var */
  237:             symtab (kill_sym, key, result);
  238:             ref->status = merr ();
  239:             break;
  240:     	
  241:     	case MREF_RT_GLOBAL:
  242:             /* call into the FreeM global handler; result in &result */
  243:             global (kill_sym, key, result);
  244:             ref->status = merr ();
  245:             break;
  246: 
  247:     	case MREF_RT_SSVN:
  248:             /* call into the SSVN code */
  249:             ssvn (kill_sym, key, result);
  250:             ref->status = merr ();
  251:             break;
  252: 
  253:     }
  254: 
  255:     stcnv_m2c (result);
  256: 
  257:     strncpy (ref->value, result, sizeof (ref->value) - 1);
  258: 
  259:     freem_release_io ();
  260:     
  261: 
  262:     return ref->status;
  263: }
  264: 
  265: short freem_data(freem_ref_t *ref) 
  266: {
  267:     char key[256];
  268:     char result[256];
  269: 
  270:     mref2str (ref, key);
  271: 
  272:     freem_return_io ();
  273: 
  274:     switch (ref->reftype) {
  275:         
  276:         case MREF_RT_LOCAL:
  277:             /* call into the symbol table */
  278:             symtab (fra_dat, key, result);
  279:             ref->status = merr ();
  280:             break;
  281:         
  282:         case MREF_RT_GLOBAL:
  283:             /* call into the FreeM global handler; result in &result */
  284:             global (fra_dat, key, result);
  285:             ref->status = merr ();
  286:             break;
  287: 
  288:         case MREF_RT_SSVN:
  289:             /* call into the SSVN code */
  290:             ssvn (fra_dat, key, result);
  291:             ref->status = merr ();
  292:             break;
  293: 
  294:     }
  295: 
  296:     stcnv_m2c (result);
  297: 
  298:     strncpy (ref->value, result, 255);
  299: 
  300:     freem_release_io ();
  301: 
  302:     return ref->status;
  303: }
  304: 
  305: short freem_order(freem_ref_t *ref) 
  306: {
  307:     char key[256];
  308:     char result[256];
  309: 
  310:     mref2str (ref, key);
  311: 
  312:     freem_return_io ();
  313: 
  314:     switch (ref->reftype) {
  315:         
  316:         case MREF_RT_LOCAL:
  317:             /* call into the symbol table for $ORDER */
  318:             symtab (fra_order, key, result);
  319:             ref->status = merr ();
  320:             break;
  321:         
  322:         case MREF_RT_GLOBAL:
  323:             /* call into the FreeM global handler; result in &result */
  324:             global (fra_order, key, result);
  325:             ref->status = merr ();
  326:             break;
  327: 
  328:         case MREF_RT_SSVN:
  329:             /* call into the SSVN code */
  330:             ssvn (fra_order, key, result);
  331:             ref->status = merr ();
  332:             break;
  333: 
  334:     }
  335: 
  336:     stcnv_m2c (result);
  337: 
  338:     strncpy (ref->value, result, 255);
  339:     freem_release_io ();
  340: 
  341:     return ref->status;
  342: }
  343: 
  344: short freem_query(freem_ref_t *ref) 
  345: {
  346:     char key[256];
  347:     char result[256];
  348: 
  349:     mref2str (ref, key);
  350: 
  351:     freem_return_io ();
  352: 
  353:     switch (ref->reftype) {
  354:         
  355:         case MREF_RT_LOCAL:
  356:             /* call into the symbol table */
  357:             symtab (fra_query, key, result);
  358:             ref->status = merr ();
  359:             break;
  360:         
  361:         case MREF_RT_GLOBAL:
  362:             /* call into the FreeM global handler; result in &result */
  363:             global (fra_query, key, result);
  364:             ref->status = merr ();
  365:             break;
  366: 
  367:         case MREF_RT_SSVN:
  368:             /* call into the SSVN code */
  369:             ssvn (fra_query, key, result);
  370:             ref->status = merr ();
  371:             break;
  372: 
  373:     }
  374: 
  375:     stcnv_m2c (result);
  376: 
  377:     strncpy (ref->value, result, 255);
  378: 
  379:     freem_release_io ();
  380: 
  381:     return ref->status;
  382: }
  383: 
  384: short freem_lock(freem_ref_t *ref, long lck_timeout)
  385: {
  386:     char key[256];
  387:     char buf[256];
  388: 
  389:     mref2str (ref, key);
  390:     snprintf (buf, sizeof (buf) - 1, "+%s\201", key);
  391: 
  392:     freem_return_io ();
  393: 
  394:     lock (buf, lck_timeout, 'l');
  395:     ref->status = merr ();
  396: 
  397:     freem_release_io ();
  398: 
  399:     return ref->status;
  400: }
  401: 
  402: short freem_unlock(freem_ref_t *ref, long lck_timeout) 
  403: {
  404:     char key[256];
  405:     char buf[256];
  406: 
  407:     mref2str (ref, key);
  408:     snprintf (buf, sizeof (buf) - 1, "-%s\201", key);
  409: 
  410:     freem_return_io ();
  411: 
  412:     lock (buf, lck_timeout, 'l');
  413:     ref->status = merr ();
  414: 
  415:     freem_release_io ();
  416: 
  417:     return ref->status;
  418: }
  419: 
  420: short freem_tstart(char *tp_id, short serial, short restartable, char **sym_save)
  421: {
  422:     return tp_tstart (tp_id, serial, restartable, sym_save);
  423: }
  424: 
  425: short freem_trestart(void)
  426: {
  427:     return tp_trestart ();
  428: }
  429: 
  430: short freem_trollback(int tp_levels)
  431: {
  432:     return tp_trollback (tp_levels);
  433: }
  434: 
  435: short freem_tcommit(void)
  436: {
  437:     return tp_tcommit ();
  438: }
  439: 
  440: int freem_tlevel(void)
  441: {
  442:     return tp_level;
  443: }
  444: 
  445: short freem_function(freem_ent_t *ent)
  446: {
  447:     register int i;
  448:     char buf[STRLEN] = {0};
  449:     char tmp[STRLEN] = {0};
  450:     char tmp1[STRLEN] = {0};
  451: 
  452:     freem_return_io ();
  453: 
  454:     if (ent->argument_count > 0) {
  455:         snprintf (buf, STRLEN - 1, "S %%ZFRMRTN=$$%s(", ent->name);
  456: 
  457:         for (i = 0; i < ent->argument_count; i++) {
  458: 
  459:             strncpy (tmp1, ent->arguments[i], STRLEN - 1);
  460:             stcnv_c2m (tmp1);
  461: 
  462:             if (znamenumeric (tmp1) == TRUE) {
  463:                 /* arguments that are canonical MUMPS numbers don't get quoted */
  464:                 snprintf (tmp, STRLEN - 1, "%s", ent->arguments[i]);
  465:             }
  466:             else {
  467:                 /* string arguments do get quoted */
  468:                 snprintf (tmp, STRLEN - 1, "\"%s\"", ent->arguments[i]);
  469:             }
  470: 
  471:             strcat (buf, tmp);
  472: 
  473:             if(i < ent->argument_count - 1) {
  474:                 strcat (buf, ",");
  475:             }
  476:         }
  477: 
  478:         strcat (buf, ")");
  479:     }
  480:     else {
  481:         snprintf (buf, STRLEN - 1, "S %%ZFRMRTN=$$%s", ent->name);
  482:     }
  483: 
  484:     stcnv_c2m (buf);
  485:     sprintf (tmp, "%%ZFRMXEC\201");
  486:     symtab (set_sym, tmp, buf);
  487:     snprintf ((char *) ztrap, ZTLEN - 1, "^%%ZFRMXEC\201");
  488: 
  489:     xecline (3);
  490:     ent->status = merr ();
  491: 
  492:     tmp[0] = NUL;
  493:     ent->value[0] = NUL;
  494: 
  495:     snprintf (tmp, sizeof (tmp) - 1, "%%ZFRMRTN\201");
  496:     symtab (get_sym, tmp, ent->value);
  497:     stcnv_m2c (ent->value);
  498: 
  499:     freem_release_io ();
  500: 
  501:     return ent->status;
  502: }
  503: 
  504: short freem_procedure(freem_ent_t *ent)
  505: {
  506:     register int i;
  507:     char buf[STRLEN] = {0};
  508:     char tmp[STRLEN] = {0};
  509:     char tmp1[STRLEN] = {0};
  510: 
  511:     freem_return_io ();
  512: 
  513:     if (ent->argument_count > 0) {
  514:         snprintf (buf, STRLEN - 1, "DO %s(", ent->name);
  515: 
  516:         for (i = 0; i < ent->argument_count; i++) {
  517: 
  518:             strncpy (tmp1, ent->arguments[i], STRLEN - 1);
  519:             stcnv_c2m (tmp1);
  520: 
  521:             if (znamenumeric (tmp1) == TRUE) {
  522:                 /* arguments that are canonical MUMPS numbers don't get quoted */
  523:                 snprintf (tmp, STRLEN - 1, "%s", ent->arguments[i]);
  524:             }
  525:             else {
  526:                 /* string arguments do get quoted */
  527:                 snprintf (tmp, STRLEN - 1, "\"%s\"", ent->arguments[i]);
  528:             }
  529: 
  530:             strcat (buf, tmp);
  531: 
  532:             if(i < ent->argument_count - 1) {
  533:                 strcat (buf, ",");
  534:             }
  535:         }
  536: 
  537:         strcat (buf, ")");
  538:     }
  539:     else {
  540:         snprintf (buf, STRLEN - 1, "DO %s", ent->name);
  541:     }
  542: 
  543:     stcnv_c2m (buf);
  544:     sprintf (tmp, "%%ZFRMXEC\201");
  545:     symtab (set_sym, tmp, buf);
  546:     
  547: 
  548:     snprintf ((char *) ztrap, ZTLEN - 1, "^%%ZFRMXEC\201");
  549: 
  550: 
  551:     xecline (3);
  552:     ent->status = merr ();
  553: 
  554:     tmp[0] = NUL;
  555:     ent->value[0] = NUL;
  556: 
  557:     freem_release_io ();
  558: 
  559:     return ent->status;
  560: }
  561: 
  562: short freem_errmsg(int code, char *msg)
  563: {
  564:     char emtmp[256];
  565:     char cvtmp[256];
  566:     
  567:     if (code > MAXERR || code < 0) {
  568:         return FALSE;
  569:     }
  570: 
  571:     stcpy (cvtmp, errmes[code]);
  572:     stcnv_m2c (cvtmp);
  573: 
  574:     merr_num_to_code (code, emtmp);
  575: 
  576:     sprintf (msg, "%s: %s", emtmp, cvtmp); 
  577:     
  578:     return TRUE;
  579: }
  580: 
  581: void freem_release_io(void)
  582: {
  583:     set_io (UNIX);
  584: }
  585: 
  586: void freem_return_io(void)
  587: {
  588:     set_io (MUMPS);
  589: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>