File:  [Coherent Logic Development] / freem / src / tp_check.c
Revision 1.7: download - view: text, annotated - select for diffs
Sun Apr 13 15:12:21 2025 UTC (3 months, 2 weeks ago) by snw
Branches: MAIN
CVS tags: HEAD
Fix transaction checkpoints on OS/2 [CLOSES #34]

    1: /*
    2:  *   $Id: tp_check.c,v 1.7 2025/04/13 15:12:21 snw Exp $
    3:  *    TP global checkpointing code
    4:  *
    5:  *  
    6:  *   Author: Serena Willis <snw@coherent-logic.com>
    7:  *    Copyright (C) 1998 MUG Deutschland
    8:  *    Copyright (C) 2022, 2025 Coherent Logic Development LLC
    9:  *
   10:  *
   11:  *   This file is part of FreeM.
   12:  *
   13:  *   FreeM is free software: you can redistribute it and/or modify
   14:  *   it under the terms of the GNU Affero Public License as published by
   15:  *   the Free Software Foundation, either version 3 of the License, or
   16:  *   (at your option) any later version.
   17:  *
   18:  *   FreeM is distributed in the hope that it will be useful,
   19:  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   20:  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   21:  *   GNU Affero Public License for more details.
   22:  *
   23:  *   You should have received a copy of the GNU Affero Public License
   24:  *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
   25:  *
   26:  *   $Log: tp_check.c,v $
   27:  *   Revision 1.7  2025/04/13 15:12:21  snw
   28:  *   Fix transaction checkpoints on OS/2 [CLOSES #34]
   29:  *
   30:  *   Revision 1.6  2025/04/13 04:22:43  snw
   31:  *   Fix snprintf calls
   32:  *
   33:  *   Revision 1.5  2025/04/09 19:52:02  snw
   34:  *   Eliminate as many warnings as possible while building with -Wall
   35:  *
   36:  *   Revision 1.4  2025/03/22 18:43:54  snw
   37:  *   Make STRLEN 255 chars and add BIGSTR macro for larger buffers
   38:  *
   39:  *   Revision 1.3  2025/03/09 19:50:47  snw
   40:  *   Second phase of REUSE compliance and header reformat
   41:  *
   42:  *
   43:  * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
   44:  * SPDX-License-Identifier: AGPL-3.0-or-later
   45:  **/
   46: 
   47: #include <stdlib.h>
   48: #include <string.h>
   49: #include <unistd.h>
   50: #include "tp_check.h"
   51: #include "mpsdef.h"
   52: #include "transact.h"
   53: #include "journal.h"
   54: #include "fs.h"
   55: 
   56: #if defined(__OS2__)
   57: # include <os2.h>
   58: #endif
   59: 
   60: short frm_global_exists(char *, char *, char *);
   61: 
   62: cptab *cptab_head[TP_MAX_NEST];
   63: 
   64: cptab *cptab_insert(int tlevel, char *global)
   65: {
   66:     cptab *t;
   67:     short g_exists;
   68:     char *gc_ns;
   69:     char *gc_pth;
   70:     
   71:     gc_ns = (char *) malloc (STRLEN * sizeof (char));
   72:     NULLPTRCHK(gc_ns,"cptab_insert");
   73: 
   74:     gc_pth = (char *) malloc (PATHLEN * sizeof (char));
   75:     NULLPTRCHK(gc_pth,"cptab_insert");
   76: 
   77:     for (t = cptab_head[tlevel]; t != NULL; t = t->next) {
   78: 
   79:         if ((strcmp (t->global, global) == 0) && (t->mode > CP_UNUSED)) {
   80:             /* found match */
   81:             return t;
   82:         }
   83: 
   84:     }
   85: 
   86:     /* insert */
   87:     t = (cptab *) malloc (sizeof (cptab));
   88:     NULLPTRCHK(t,"cptab_insert");
   89: 
   90:     t->global = (char *) malloc (sizeof (char) * (strlen (global) + 1));
   91:     NULLPTRCHK(t->global,"cptab_insert");
   92: 
   93:     strcpy (t->global, global);
   94: 
   95:     g_exists = frm_global_exists (gc_ns, gc_pth, global);
   96:     
   97:     t->file = (char *) malloc (sizeof (char) * (strlen (gc_pth)));
   98:     NULLPTRCHK(t->file,"cptab_insert");
   99: 
  100:     t->cp_file = (char *) malloc (sizeof (char) * PATHLEN);
  101:     NULLPTRCHK(t->cp_file,"cptab_insert");
  102:     
  103:     strcpy (t->file, gc_pth);
  104:     stcnv_m2c (t->file);
  105:     
  106:     snprintf (t->cp_file, PATHLEN - 1, "%s.%d.%d.chk", t->file, pid, tp_level);
  107: 
  108:     free (gc_ns);
  109:     free (gc_pth);
  110:     
  111:     if (!g_exists) {
  112:         t->mode = CP_REMOVE;
  113:     }
  114:     else {
  115:         t->mode = CP_RESTORE;
  116:     }
  117: 
  118:     t->next = cptab_head[tlevel];
  119:     cptab_head[tlevel] = t;
  120: 
  121:     return t;
  122: }
  123: 
  124: short cptab_precommit(int tlevel)
  125: {
  126:     cptab *t;
  127:     /*char *cmd;*/
  128:     char *pctmp;
  129:     int rc;
  130: 
  131:     /*
  132:     cmd = (char *) malloc (STRLEN * sizeof (char));
  133:     NULLPTRCHK(cmd,"cptab_precommit");
  134:     */
  135:     
  136:     pctmp = (char *) malloc (STRLEN * sizeof (char));
  137:     NULLPTRCHK(pctmp,"cptab_precommit");
  138:     
  139:     for (t = cptab_head[tlevel]; t != NULL; t = t->next) {
  140:         
  141:         if (t->mode == CP_RESTORE) {
  142: 
  143:             /*
  144:             snprintf (cmd, STRLEN - 1, "/bin/cp %s %s", t->file, t->cp_file);
  145:             rc = system (cmd);
  146:             */
  147:             
  148:             rc = cp (t->cp_file, t->file);
  149:             
  150:             if (rc != 0) {
  151: 
  152:                 strcpy (pctmp, t->file);
  153:                 stcnv_c2m (pctmp);
  154:                 
  155:                 jnl_ent_write (JNLA_CHECKPOINT_FAIL, " \201", pctmp);
  156:                 
  157:                 /*free (cmd);*/
  158:                 free (pctmp);
  159: 
  160:                 return FALSE;
  161:                 
  162:             }
  163:             else {
  164: 
  165:                 strcpy (pctmp, t->file);
  166:                 stcnv_c2m (pctmp);
  167:                 
  168:                 jnl_ent_write (JNLA_CHECKPOINT_OK, " \201", pctmp);
  169: 
  170:             }
  171: 
  172:         }
  173:         
  174:     }
  175:     
  176:     /*free (cmd);*/
  177:     free (pctmp);
  178:     
  179:     return TRUE;    
  180: }
  181: 
  182: void cptab_postcommit(int tlevel)
  183: {
  184:     cptab *t;
  185:     /*char *cmd;*/
  186: 
  187:     /*
  188:     cmd = (char *) malloc (STRLEN * sizeof (char));
  189:     NULLPTRCHK(cmd,"cptab_postcommit");
  190:     */
  191: 
  192:     for (t = cptab_head[tlevel]; t != NULL; t = t->next) {
  193: 
  194:         if (t->mode == CP_RESTORE) {
  195:             /*
  196:             snprintf (cmd, STRLEN - 1, "/bin/rm -f '%s'", t->cp_file);
  197:             rc = system (cmd);
  198:             */
  199:             unlink (t->cp_file);
  200:         }
  201:         
  202:     }
  203: 
  204:     cptab_head[tlevel] = NULL;
  205: }
  206: 
  207: short cptab_rollback(int tlevel)
  208: {
  209:     cptab *t;
  210:     int rc;
  211: 
  212:     for (t = cptab_head[tlevel]; t != NULL; t = t->next) {
  213:         
  214:         switch (t->mode) {
  215: 
  216:             case CP_REMOVE:
  217:                 unlink (t->file);
  218:                 break;
  219: 
  220:             case CP_RESTORE:
  221: #if !defined(__OS2__)                
  222:                 rc = cp (t->file, t->cp_file);
  223: #else
  224:                 rc = DosCopy (t->cp_file, t->file, 1);
  225: #endif                
  226:                 if (rc != 0) {
  227:                     cptab_head[tlevel] = NULL;
  228:                     /*free (cmd);*/
  229:                     return FALSE;
  230:                 }
  231: 
  232:                 unlink (t->cp_file);
  233:                 if (rc != 0) {
  234:                     cptab_head[tlevel] = NULL;
  235:                     /*free (cmd);*/
  236:                     return FALSE;
  237:                 }
  238: 
  239:                 break;
  240: 
  241:                 
  242:         }
  243: 
  244:     }
  245: 
  246:     cptab_head[tlevel] = NULL;
  247:     
  248:     return TRUE;
  249: 
  250: }
  251: 
  252: void cptab_dump(int tlevel)
  253: {
  254:     cptab *gt;
  255:     char cp_mode[15];
  256:     
  257:     printf ("\n  Global database checkpoints:\n");
  258: 
  259:     printf ("\n   %-30s%-20s%s\n", "GLOBAL", "MODE", "FILES");
  260:     printf ("   %-30s%-20s%s\n", "------", "----", "-----");
  261: 
  262:     for (gt = cptab_head[tlevel]; gt != NULL; gt = gt->next) {
  263: 
  264:         switch (gt->mode) {
  265: 
  266:             case CP_UNUSED:
  267:                 strcpy (cp_mode, "CP_UNUSED");
  268:                 break;
  269: 
  270:             case CP_REMOVE:
  271:                 strcpy (cp_mode, "CP_REMOVE");
  272:                 break;
  273: 
  274:             case CP_RESTORE:
  275:                 strcpy (cp_mode, "CP_RESTORE");
  276:                 break;
  277: 
  278:         }
  279: 
  280:         if (gt->mode > CP_UNUSED) {
  281:             printf ("   %-30s%-20sIN:   %s\n", gt->global, cp_mode, gt->file); 
  282:         }
  283:         else {
  284:             printf ("   N/A\n");
  285:         }
  286:         
  287:         if (gt->mode == CP_RESTORE) {
  288:             printf ("   %-30s%-20sOUT:  %s\n", "", "", gt->cp_file);
  289:         }
  290:         
  291:     }
  292: }
  293: 

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