File:  [Coherent Logic Development] / freem / src / fma_journals.c
Revision 1.1: download - view: text, annotated - select for diffs
Sun Jan 19 02:04:04 2025 UTC (9 months ago) by snw
Branches: MAIN
CVS tags: HEAD
Initial revision

    1: /*
    2:  *                            *
    3:  *                           * *
    4:  *                          *   *
    5:  *                     ***************
    6:  *                      * *       * *
    7:  *                       *  MUMPS  *
    8:  *                      * *       * *
    9:  *                     ***************
   10:  *                          *   *
   11:  *                           * *
   12:  *                            *
   13:  *
   14:  *   fma_journals.c
   15:  *    Journal utilities for fmadm
   16:  *
   17:  *  
   18:  *   Author: Serena Willis <jpw@coherent-logic.com>
   19:  *    Copyright (C) 1998 MUG Deutschland
   20:  *    Copyright (C) 2020 Coherent Logic Development LLC
   21:  *
   22:  *
   23:  *   This file is part of FreeM.
   24:  *
   25:  *   FreeM is free software: you can redistribute it and/or modify
   26:  *   it under the terms of the GNU Affero Public License as published by
   27:  *   the Free Software Foundation, either version 3 of the License, or
   28:  *   (at your option) any later version.
   29:  *
   30:  *   FreeM is distributed in the hope that it will be useful,
   31:  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
   32:  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   33:  *   GNU Affero Public License for more details.
   34:  *
   35:  *   You should have received a copy of the GNU Affero Public License
   36:  *   along with FreeM.  If not, see <https://www.gnu.org/licenses/>.
   37:  *
   38:  **/
   39: 
   40: #include <stdlib.h>
   41: #include <stdio.h>
   42: #include <stdlib.h>
   43: #include <string.h>
   44: #include <dirent.h>
   45: #include <time.h>
   46: #include <unistd.h>
   47: #include <sys/types.h>
   48: #include <sys/stat.h>
   49: #include <fcntl.h>
   50: #include <errno.h>
   51: 
   52: #include "fmadm.h"
   53: #include "jnldefs.h"
   54: 
   55: void cvt_key (char *buf, char *key);
   56: extern short ierr;
   57: 
   58: int fma_journals_examine (int optc, char **opts)
   59: {
   60:     register int i;
   61:     register int k;
   62:     int fd;
   63:     unsigned long siz;
   64:     unsigned long ct;
   65:     
   66:     char buf[2048];
   67:     char kbuf[1024];
   68:     char *tbuf;
   69: 
   70:     char dbuf[2049];
   71:     
   72:     jnl_hdr_t hdr;
   73:     jnl_ent_t ent;
   74:     
   75:     if ((fd = open (fma_journal_path, O_RDONLY)) == -1) {
   76:         fprintf (stderr, "fmadm:  error %d opening journal file %s (%s)\n", errno, fma_journal_path, strerror (errno));
   77:         
   78:         exit (2);
   79:     }
   80:     
   81:     if (read (fd, &hdr, sizeof (jnl_hdr_t)) == -1) {
   82:         fprintf (stderr, "fmadm:  error %d reading header from journal file %s (%s)\n", errno, fma_journal_path, strerror (errno));
   83:         
   84:         exit (3);
   85:     }
   86: 
   87:     printf ("\nFreeM Journal Dump\n");
   88:     printf ("------------------\n\n");
   89: 
   90:     printf ("Namespace:               %s\n", fma_namespace);
   91:     printf ("Journal File:            %s\n", fma_journal_path);
   92:     printf ("Journal Format Version:  %d\n", hdr.fmt_version);
   93:     printf ("Cut Threshold:           %s bytes\n", fma_journal_cut_threshold);
   94:     
   95:     lseek (fd, 0L, SEEK_SET);
   96:     siz = lseek (fd, 0L, SEEK_END);
   97:     
   98:     ct = (siz - sizeof (jnl_hdr_t)) / sizeof (jnl_ent_t);
   99:     
  100:     printf ("Journal Entries:         %ld\n\n", ct);
  101: 
  102:     printf ("%-26s %-6s %-7s %-10s %s\n", "DATE", "PID", "TRNID", "ACTION", "DATA");
  103:     printf ("%-26s %-6s %-7s %-10s %s\n", "----", "---", "-----", "------", "----");
  104:     
  105:     lseek (fd, sizeof (jnl_hdr_t), SEEK_SET);
  106:     
  107:     for (i = 0; i < ct; i++) {
  108:         
  109:         read (fd, &ent, sizeof (jnl_ent_t));
  110:         
  111:         switch (ent.action) {
  112:             
  113:             case JNLA_TSTART:
  114:                 strcpy (buf, "TSTART");
  115:                 break;
  116:                 
  117:             case JNLA_TROLLBACK:
  118:                 strcpy (buf, "TROLLBACK");
  119:                 break;
  120:                 
  121:             case JNLA_TCOMMIT:
  122:                 strcpy (buf, "TCOMMIT");
  123:                 break;
  124:                 
  125:             case JNLA_SET:
  126:                 strcpy (buf, "SET");
  127:                 break;
  128:                 
  129:             case JNLA_KILL:
  130:                 strcpy (buf, "KILL");
  131:                 break;
  132: 		
  133:         }
  134:         
  135:         cvt_key (kbuf, ent.key);
  136: 
  137:         
  138:         tbuf = ctime (&ent.ts);
  139:         tbuf[strlen(tbuf) - 1] = '\0';
  140: 
  141:         if (ent.action == JNLA_SET) {
  142: 
  143:             snprintf (dbuf, 2049, "%s=%s", kbuf, ent.data);
  144: 
  145:             for (k = 0; k < strlen (dbuf); k++) {
  146:                 if (dbuf[k] == '\201') dbuf[k] = '\0';
  147:             }
  148:         
  149:             printf ("%-26s %-6d %-7ld %-10s %s\n", tbuf, ent.pid, ent.tran_id, buf, dbuf);
  150: 
  151:         }
  152:         else {
  153:             printf ("%-26s %-6d %-7ld %-10s %s\n", tbuf, ent.pid, ent.tran_id, buf, kbuf);
  154:         }
  155:                 
  156:     }
  157: 
  158:     return 0;
  159:     
  160: }
  161: 
  162: int fma_journals_restore (int optc, char **opts)
  163: {
  164: 
  165:     register int i;
  166:     register int k;
  167:     int fd;
  168:     unsigned long siz;
  169:     unsigned long ct;
  170:     
  171:     char kbuf[1024];
  172:     char *tbuf;
  173: 
  174:     char dbuf[2049];
  175:     
  176:     jnl_hdr_t hdr;
  177:     jnl_ent_t ent;
  178:     
  179:     if ((fd = open (fma_journal_path, O_RDONLY)) == -1) {
  180:         fprintf (stderr, "error: error %d opening journal file %s\n", errno, fma_journal_path);
  181:         
  182:         exit (2);
  183:     }
  184:     
  185:     if (read (fd, &hdr, sizeof (jnl_hdr_t)) == -1) {
  186:         fprintf (stderr, "error: error %d reading header from journal file %s\n", errno, fma_journal_path);
  187:         
  188:         exit (3);
  189:     }
  190: 
  191:     printf ("\nFreeM Journal Playback\n");
  192:     printf ("----------------------\n\n");
  193: 
  194:     printf ("Namespace:               %s\n", fma_namespace);
  195:     printf ("Journal File:            %s\n", fma_journal_path);
  196:     printf ("Journal Format Version:  %d\n", hdr.fmt_version);
  197:     printf ("Cut Threshold:           %s bytes\n", fma_journal_cut_threshold);
  198:     
  199:     lseek (fd, 0L, SEEK_SET);
  200:     siz = lseek (fd, 0L, SEEK_END);
  201:     
  202:     ct = (siz - sizeof (jnl_hdr_t)) / sizeof (jnl_ent_t);
  203:     
  204:     printf ("Journal Entries:         %ld\n\n", ct);
  205: 
  206:     
  207:     lseek (fd, sizeof (jnl_hdr_t), SEEK_SET);
  208:     
  209:     for (i = 0; i < ct; i++) {
  210:         
  211:         read (fd, &ent, sizeof (jnl_ent_t));
  212:         
  213:         switch (ent.action) {
  214:             
  215:             case JNLA_TSTART:
  216:                 printf (" Played back TSTART (transaction id %ld)\n", ent.tran_id);
  217:                 break;
  218:                 
  219:             case JNLA_TROLLBACK:
  220:                 printf (" Played back TROLLBACK (transaction id %ld)\n", ent.tran_id);
  221:                 break;
  222:                 
  223:             case JNLA_TCOMMIT:
  224:                 printf (" Played back TCOMMIT (transaction id %ld)\n", ent.tran_id);                
  225:                 break;
  226:                 
  227:             case JNLA_SET:
  228:                 global (set_sym, ent.key, ent.data);
  229:                 printf (" Played back SET (transaction id %ld)\n", ent.tran_id);                
  230:                 break;
  231:                 
  232:             case JNLA_KILL:                
  233:                 global (kill_sym, ent.key, ent.data);
  234:                 printf (" Played back KILL (transaction id %ld)\n", ent.tran_id);
  235:                 break;
  236: 		
  237:         }
  238:            
  239:     }
  240: 
  241:     return 0;
  242:     
  243: }
  244: 
  245: 
  246: void cvt_key (char *buf, char *key)
  247: {
  248:     int i;
  249:     int j = 0;
  250:     int first = 1;
  251:     
  252:     if (key[0] == '\0') {
  253:         buf[0] = '\0';
  254:         
  255:         return;
  256:     }
  257:     
  258:     for(i = 0; i < 1023; i++) {
  259:         
  260:         switch (key[i]) {
  261:             
  262:             case '\201':
  263:                 if (first == 0) {
  264:                     buf[j] = ')';
  265:                     buf[j + 1] = '\0';
  266:                 }
  267:                 else {
  268:                     buf[j] = '\0';
  269:                 }
  270:                 return;
  271:                 
  272:             case '\202':
  273:                 if (first == 1) {
  274:                     buf[j] = '(';
  275:                     first = 0;
  276:                 }
  277:                 else {
  278:                     buf[j] = ',';
  279:                 }
  280:                 
  281:                 break;
  282:                 
  283:             default:
  284:                 buf[j] = key[i];
  285:                 break;
  286:         }
  287:         
  288:         j++;
  289:     }
  290: 
  291: }

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