Annotation of freem/src/fma_journals.c, revision 1.5

1.1       snw         1: /*
1.5     ! snw         2:  *   $Id: fma_journals.c,v 1.4 2025/04/09 19:52:02 snw Exp $
1.1       snw         3:  *    Journal utilities for fmadm
                      4:  *
                      5:  *  
1.2       snw         6:  *   Author: Serena Willis <snw@coherent-logic.com>
1.1       snw         7:  *    Copyright (C) 1998 MUG Deutschland
1.3       snw         8:  *    Copyright (C) 2020, 2025 Coherent Logic Development LLC
1.1       snw         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:  *
1.4       snw        26:  *   $Log: fma_journals.c,v $
1.5     ! snw        27:  *   Revision 1.4  2025/04/09 19:52:02  snw
        !            28:  *   Eliminate as many warnings as possible while building with -Wall
        !            29:  *
1.4       snw        30:  *   Revision 1.3  2025/03/09 19:14:25  snw
                     31:  *   First phase of REUSE compliance and header reformat
                     32:  *
1.3       snw        33:  *
                     34:  * SPDX-FileCopyrightText:  (C) 2025 Coherent Logic Development LLC
                     35:  * SPDX-License-Identifier: AGPL-3.0-or-later 
1.1       snw        36:  **/
                     37: 
                     38: #include <stdlib.h>
                     39: #include <stdio.h>
                     40: #include <stdlib.h>
                     41: #include <string.h>
                     42: #include <dirent.h>
                     43: #include <time.h>
                     44: #include <unistd.h>
                     45: #include <sys/types.h>
                     46: #include <sys/stat.h>
                     47: #include <fcntl.h>
                     48: #include <errno.h>
                     49: 
                     50: #include "fmadm.h"
                     51: #include "jnldefs.h"
                     52: 
                     53: void cvt_key (char *buf, char *key);
                     54: extern short ierr;
                     55: 
                     56: int fma_journals_examine (int optc, char **opts)
                     57: {
                     58:     register int i;
                     59:     register int k;
                     60:     int fd;
                     61:     unsigned long siz;
                     62:     unsigned long ct;
                     63:     
                     64:     char buf[2048];
                     65:     char kbuf[1024];
                     66:     char *tbuf;
                     67: 
                     68:     char dbuf[2049];
                     69:     
                     70:     jnl_hdr_t hdr;
                     71:     jnl_ent_t ent;
                     72:     
                     73:     if ((fd = open (fma_journal_path, O_RDONLY)) == -1) {
                     74:         fprintf (stderr, "fmadm:  error %d opening journal file %s (%s)\n", errno, fma_journal_path, strerror (errno));
                     75:         
                     76:         exit (2);
                     77:     }
                     78:     
                     79:     if (read (fd, &hdr, sizeof (jnl_hdr_t)) == -1) {
                     80:         fprintf (stderr, "fmadm:  error %d reading header from journal file %s (%s)\n", errno, fma_journal_path, strerror (errno));
                     81:         
                     82:         exit (3);
                     83:     }
                     84: 
                     85:     printf ("\nFreeM Journal Dump\n");
                     86:     printf ("------------------\n\n");
                     87: 
                     88:     printf ("Namespace:               %s\n", fma_namespace);
                     89:     printf ("Journal File:            %s\n", fma_journal_path);
                     90:     printf ("Journal Format Version:  %d\n", hdr.fmt_version);
                     91:     printf ("Cut Threshold:           %s bytes\n", fma_journal_cut_threshold);
                     92:     
                     93:     lseek (fd, 0L, SEEK_SET);
                     94:     siz = lseek (fd, 0L, SEEK_END);
                     95:     
                     96:     ct = (siz - sizeof (jnl_hdr_t)) / sizeof (jnl_ent_t);
                     97:     
                     98:     printf ("Journal Entries:         %ld\n\n", ct);
                     99: 
                    100:     printf ("%-26s %-6s %-7s %-10s %s\n", "DATE", "PID", "TRNID", "ACTION", "DATA");
                    101:     printf ("%-26s %-6s %-7s %-10s %s\n", "----", "---", "-----", "------", "----");
                    102:     
                    103:     lseek (fd, sizeof (jnl_hdr_t), SEEK_SET);
                    104:     
                    105:     for (i = 0; i < ct; i++) {
                    106:         
                    107:         read (fd, &ent, sizeof (jnl_ent_t));
                    108:         
                    109:         switch (ent.action) {
                    110:             
                    111:             case JNLA_TSTART:
                    112:                 strcpy (buf, "TSTART");
                    113:                 break;
                    114:                 
                    115:             case JNLA_TROLLBACK:
                    116:                 strcpy (buf, "TROLLBACK");
                    117:                 break;
                    118:                 
                    119:             case JNLA_TCOMMIT:
                    120:                 strcpy (buf, "TCOMMIT");
                    121:                 break;
                    122:                 
                    123:             case JNLA_SET:
                    124:                 strcpy (buf, "SET");
                    125:                 break;
                    126:                 
                    127:             case JNLA_KILL:
                    128:                 strcpy (buf, "KILL");
                    129:                 break;
                    130:                
                    131:         }
                    132:         
                    133:         cvt_key (kbuf, ent.key);
                    134: 
                    135:         
                    136:         tbuf = ctime (&ent.ts);
                    137:         tbuf[strlen(tbuf) - 1] = '\0';
                    138: 
                    139:         if (ent.action == JNLA_SET) {
                    140: 
1.5     ! snw       141:             snprintf (dbuf, sizeof (dbuf) - 1, "%s=%s", kbuf, ent.data);
1.1       snw       142: 
                    143:             for (k = 0; k < strlen (dbuf); k++) {
                    144:                 if (dbuf[k] == '\201') dbuf[k] = '\0';
                    145:             }
                    146:         
                    147:             printf ("%-26s %-6d %-7ld %-10s %s\n", tbuf, ent.pid, ent.tran_id, buf, dbuf);
                    148: 
                    149:         }
                    150:         else {
                    151:             printf ("%-26s %-6d %-7ld %-10s %s\n", tbuf, ent.pid, ent.tran_id, buf, kbuf);
                    152:         }
                    153:                 
                    154:     }
                    155: 
                    156:     return 0;
                    157:     
                    158: }
                    159: 
                    160: int fma_journals_restore (int optc, char **opts)
                    161: {
                    162: 
                    163:     register int i;
                    164:     int fd;
                    165:     unsigned long siz;
                    166:     unsigned long ct;
1.4       snw       167:         
1.1       snw       168:     jnl_hdr_t hdr;
                    169:     jnl_ent_t ent;
                    170:     
                    171:     if ((fd = open (fma_journal_path, O_RDONLY)) == -1) {
                    172:         fprintf (stderr, "error: error %d opening journal file %s\n", errno, fma_journal_path);
                    173:         
                    174:         exit (2);
                    175:     }
                    176:     
                    177:     if (read (fd, &hdr, sizeof (jnl_hdr_t)) == -1) {
                    178:         fprintf (stderr, "error: error %d reading header from journal file %s\n", errno, fma_journal_path);
                    179:         
                    180:         exit (3);
                    181:     }
                    182: 
                    183:     printf ("\nFreeM Journal Playback\n");
                    184:     printf ("----------------------\n\n");
                    185: 
                    186:     printf ("Namespace:               %s\n", fma_namespace);
                    187:     printf ("Journal File:            %s\n", fma_journal_path);
                    188:     printf ("Journal Format Version:  %d\n", hdr.fmt_version);
                    189:     printf ("Cut Threshold:           %s bytes\n", fma_journal_cut_threshold);
                    190:     
                    191:     lseek (fd, 0L, SEEK_SET);
                    192:     siz = lseek (fd, 0L, SEEK_END);
                    193:     
                    194:     ct = (siz - sizeof (jnl_hdr_t)) / sizeof (jnl_ent_t);
                    195:     
                    196:     printf ("Journal Entries:         %ld\n\n", ct);
                    197: 
                    198:     
                    199:     lseek (fd, sizeof (jnl_hdr_t), SEEK_SET);
                    200:     
                    201:     for (i = 0; i < ct; i++) {
                    202:         
                    203:         read (fd, &ent, sizeof (jnl_ent_t));
                    204:         
                    205:         switch (ent.action) {
                    206:             
                    207:             case JNLA_TSTART:
                    208:                 printf (" Played back TSTART (transaction id %ld)\n", ent.tran_id);
                    209:                 break;
                    210:                 
                    211:             case JNLA_TROLLBACK:
                    212:                 printf (" Played back TROLLBACK (transaction id %ld)\n", ent.tran_id);
                    213:                 break;
                    214:                 
                    215:             case JNLA_TCOMMIT:
                    216:                 printf (" Played back TCOMMIT (transaction id %ld)\n", ent.tran_id);                
                    217:                 break;
                    218:                 
                    219:             case JNLA_SET:
                    220:                 global (set_sym, ent.key, ent.data);
                    221:                 printf (" Played back SET (transaction id %ld)\n", ent.tran_id);                
                    222:                 break;
                    223:                 
                    224:             case JNLA_KILL:                
                    225:                 global (kill_sym, ent.key, ent.data);
                    226:                 printf (" Played back KILL (transaction id %ld)\n", ent.tran_id);
                    227:                 break;
                    228:                
                    229:         }
                    230:            
                    231:     }
                    232: 
                    233:     return 0;
                    234:     
                    235: }
                    236: 
                    237: 
                    238: void cvt_key (char *buf, char *key)
                    239: {
                    240:     int i;
                    241:     int j = 0;
                    242:     int first = 1;
                    243:     
                    244:     if (key[0] == '\0') {
                    245:         buf[0] = '\0';
                    246:         
                    247:         return;
                    248:     }
                    249:     
                    250:     for(i = 0; i < 1023; i++) {
                    251:         
                    252:         switch (key[i]) {
                    253:             
                    254:             case '\201':
                    255:                 if (first == 0) {
                    256:                     buf[j] = ')';
                    257:                     buf[j + 1] = '\0';
                    258:                 }
                    259:                 else {
                    260:                     buf[j] = '\0';
                    261:                 }
                    262:                 return;
                    263:                 
                    264:             case '\202':
                    265:                 if (first == 1) {
                    266:                     buf[j] = '(';
                    267:                     first = 0;
                    268:                 }
                    269:                 else {
                    270:                     buf[j] = ',';
                    271:                 }
                    272:                 
                    273:                 break;
                    274:                 
                    275:             default:
                    276:                 buf[j] = key[i];
                    277:                 break;
                    278:         }
                    279:         
                    280:         j++;
                    281:     }
                    282: 
                    283: }

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