Annotation of freem/src/fma_routines.c, revision 1.1
1.1 ! snw 1: /*
! 2: * *
! 3: * * *
! 4: * * *
! 5: * ***************
! 6: * * * * *
! 7: * * MUMPS *
! 8: * * * * *
! 9: * ***************
! 10: * * *
! 11: * * *
! 12: * *
! 13: *
! 14: * fma_routines.c
! 15: * fmadm - routines
! 16: *
! 17: *
! 18: * Author: Serena Willis <jpw@coherent-logic.com>
! 19: * Copyright (C) 1998 MUG Deutschland
! 20: * Copyright (C) 2020, 2023 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 <stdio.h>
! 41: #include <stdlib.h>
! 42: #include <string.h>
! 43: #include <dirent.h>
! 44: #include <stdlib.h>
! 45: #include <time.h>
! 46: #include <unistd.h>
! 47: #include <sys/types.h>
! 48: #include <sys/stat.h>
! 49: #include <ctype.h>
! 50: #include <errno.h>
! 51:
! 52: #include "fmadm.h"
! 53: #include "iniconf.h"
! 54:
! 55: int fma_do_export (FILE *out, char *rtn_name);
! 56: char *fma_trim_string(char *str);
! 57:
! 58: int fma_routines_list (int optc, char **opts)
! 59: {
! 60:
! 61: DIR *dir;
! 62: struct dirent *ent;
! 63:
! 64: char filename[STRLEN];
! 65: char *rtnname;
! 66: char *rtnext;
! 67:
! 68: int ct = 0;
! 69:
! 70: printf ("\nFreeM Routine Listing\n");
! 71: printf ("---------------------\n\n");
! 72:
! 73: printf ("Namespace: %s\n", fma_namespace);
! 74: printf ("Routine Path: %s\n\n", fma_routine_path);
! 75:
! 76: if ((dir = opendir (fma_routine_path)) == NULL) {
! 77: fprintf (stderr, "fmadm: could not open routine directory %s\n", fma_routine_path);
! 78: return 1;
! 79: }
! 80:
! 81: while ((ent = readdir (dir)) != NULL) {
! 82:
! 83: strncpy (filename, ent->d_name, STRLEN - 1);
! 84:
! 85: rtnname = strtok (filename, ".");
! 86: rtnext = strtok (NULL, ".");
! 87:
! 88: if (rtnext != NULL && strncmp (rtnext, "m", STRLEN - 1) == 0) {
! 89: printf (" %s\n", rtnname);
! 90: ct++;
! 91: }
! 92:
! 93: }
! 94:
! 95: printf ("\n\n - %d routines found\n\n", ct);
! 96: closedir (dir);
! 97:
! 98: return 0;
! 99:
! 100: }
! 101:
! 102: int fma_routines_edit (int optc, char **opts)
! 103: {
! 104: FILE *fp;
! 105: char rpath[STRLEN];
! 106: char ecmd[STRLEN];
! 107: char *editor;
! 108:
! 109: if (optc < fma_min_args) {
! 110: fprintf (stderr, "fmadm: must supply routine name\n");
! 111: return 1;
! 112: }
! 113:
! 114:
! 115: if ((editor = getenv("EDITOR")) == NULL) {
! 116:
! 117: if ((editor = (char *) malloc (3 * sizeof (char))) == NULL) {
! 118: fprintf (stderr, "fmadm: could not acquire memory\n");
! 119: return 1;
! 120: }
! 121:
! 122: strncpy (editor, "vi", 3);
! 123:
! 124: }
! 125:
! 126: snprintf (rpath, STRLEN - 1, "%s/%s.m", fma_routine_path, opts[fma_base_opt]);
! 127:
! 128: if (file_exists (rpath) == FALSE) {
! 129: if ((fp = fopen (rpath, "w")) == NULL) {
! 130: fprintf (stderr, "fmadm: error %d creating routine %s (%s)\n", errno, opts[1], strerror (errno));
! 131:
! 132: return 1;
! 133: }
! 134:
! 135: fprintf (fp, "%s ; Created by FreeM Administrator\n QUIT\n", opts[1]);
! 136: fclose (fp);
! 137:
! 138: }
! 139:
! 140: snprintf (ecmd, STRLEN - 1, "%s %s", editor, rpath);
! 141: system (ecmd);
! 142:
! 143: return 0;
! 144:
! 145: }
! 146:
! 147: int fma_routines_examine (int optc, char **opts)
! 148: {
! 149:
! 150: FILE *fp;
! 151: char c;
! 152: char rpath[STRLEN];
! 153: /* char *editor; */
! 154:
! 155: if (optc < fma_min_args) {
! 156: fprintf (stderr, "fmadm: must supply routine name\n");
! 157: return 1;
! 158: }
! 159:
! 160: snprintf (rpath, STRLEN - 1, "%s/%s.m", fma_routine_path, opts[fma_base_opt]);
! 161:
! 162: if (file_exists (rpath) == FALSE) {
! 163: fprintf (stderr, "fmadm: routine %s does not exist in namespace %s\n", opts[1], fma_namespace);
! 164: return 1;
! 165: }
! 166:
! 167: if ((fp = fopen (rpath, "r")) == NULL) {
! 168: fprintf (stderr, "fmadm: could not open routine %s\n", opts[1]);
! 169: return 1;
! 170: }
! 171:
! 172: while ((c = fgetc (fp)) != EOF) putchar (c);
! 173:
! 174: fclose (fp);
! 175:
! 176: putchar ('\n');
! 177:
! 178: return 0;
! 179:
! 180: }
! 181:
! 182: int fma_routines_backup (int optc, char **opts)
! 183: {
! 184: time_t t = time (NULL);
! 185: struct tm *buf;
! 186: char rcmd[STRLEN];
! 187: char backup_filename[STRLEN];
! 188: char dtstamp[STRLEN];
! 189: char bup_path[STRLEN];
! 190:
! 191: buf = gmtime (&t);
! 192:
! 193: if (optc > 1) {
! 194: strncpy (bup_path, opts[fma_base_opt], STRLEN - 1);
! 195: }
! 196: else {
! 197: strncpy (bup_path, "/tmp", STRLEN - 1);
! 198: }
! 199:
! 200: snprintf (dtstamp, STRLEN - 1, "%d%02d%02d%02d%02d%02d", buf->tm_year, buf->tm_mon, buf->tm_mday, buf->tm_hour, buf->tm_min, buf->tm_sec);
! 201: snprintf (backup_filename, STRLEN - 1, "%s/freem-routines-backup-%s-%s.tar", bup_path, fma_namespace, dtstamp);
! 202:
! 203: printf ("\nFreeM Routine Backup\n");
! 204: printf ("--------------------\n\n");
! 205:
! 206: printf ("Namespace: %s\n", fma_namespace);
! 207: printf ("Routine Path: %s\n", fma_routine_path);
! 208: printf ("Backup Location: %s\n", bup_path);
! 209: printf ("Backup Filename: %s\n\n", backup_filename);
! 210:
! 211: snprintf (rcmd, STRLEN - 1, "tar cvf %s %s/*.m", backup_filename, fma_routine_path);
! 212: system (rcmd);
! 213:
! 214: printf ("\n\nBackup completed.\n\n");
! 215:
! 216: return 0;
! 217:
! 218: }
! 219:
! 220: int fma_routines_restore (int optc, char **opts)
! 221: {
! 222: return 0;
! 223: }
! 224:
! 225: char *fma_trim_string(char *str)
! 226: {
! 227:
! 228: char *end;
! 229:
! 230: while (isspace ((unsigned char) *str)) str++;
! 231:
! 232: if (*str == 0) return str;
! 233:
! 234: end = str + strlen (str) - 1;
! 235:
! 236: while (end > str && isspace ((unsigned char) *end)) end--;
! 237:
! 238: end[1] = '\0';
! 239:
! 240: return str;
! 241:
! 242: }
! 243:
! 244: int fma_routines_import (int optc, char **opts)
! 245: {
! 246: int usr_loaded = 0;
! 247: int pct_loaded = 0;
! 248: int next_routine_flag = FALSE;
! 249: int rtn_open = FALSE;
! 250: int rtn_overwrite = TRUE;
! 251: long ln = 0;
! 252:
! 253: char pct_rtn_path[4096];
! 254: char usr_rtn_path[4096];
! 255: char namespace[4096];
! 256: char roufile[4096];
! 257: char line[STRLEN];
! 258: char *trimmed_line;
! 259:
! 260: char filename[4096];
! 261: FILE *archive = NULL;
! 262: FILE *rtn = NULL;
! 263:
! 264: char *parsed_line;
! 265:
! 266: strncpy (namespace, fma_namespace, 512 - 1);
! 267: strncpy (filename, opts[fma_base_opt], 4096 - 1);
! 268:
! 269: if (optc < fma_min_args) {
! 270: fprintf (stderr, "usage: fmadm import routine <namespace> <rsav-file>\n");
! 271: return 1;
! 272: }
! 273:
! 274: if (strncmp (fma_namespace, "SYSTEM", STRLEN - 1) != 0) {
! 275:
! 276: if (get_conf ("SYSTEM", "routines_path", pct_rtn_path) == FALSE) {
! 277: fprintf (stderr, "fmadm: could not determine percent routine access path from configuration for namespace '%s'.\n", namespace);
! 278:
! 279: return 1;
! 280: }
! 281:
! 282: }
! 283: else {
! 284: strncpy (pct_rtn_path, fma_routine_path, 4096 - 1);
! 285: }
! 286:
! 287:
! 288: if (get_conf (namespace, "routines_path", usr_rtn_path) == FALSE) {
! 289: fprintf (stderr, "fmadm: could not determine user routine access path from configuration for namespace '%s'.\n", namespace);
! 290:
! 291: return 1;
! 292: }
! 293:
! 294: if ((archive = fopen (filename, "r")) == NULL) {
! 295: fprintf (stderr, "fmadm: could not open routine archive '%s'.\n", filename);
! 296:
! 297: return 1;
! 298: }
! 299:
! 300: printf ("\nFreeM Routine Import\n");
! 301: printf ("--------------------\n\n");
! 302:
! 303: printf ("Namespace: %s\n", fma_namespace);
! 304: printf ("Archive: %s\n", filename);
! 305: printf ("Routine Path: %s\n", usr_rtn_path);
! 306: printf ("%% Routine Path: %s\n\n", pct_rtn_path);
! 307:
! 308: /* read routine archive line-by-line */
! 309: while (fgets(line, STRLEN - 1, archive) != NULL) {
! 310:
! 311: if (line[strlen(line) - 1] == '\n') line[strlen(line) - 1] = '\0';
! 312:
! 313: ln++;
! 314:
! 315: if ((ln == 1) || (ln == 2)) {
! 316: printf("%s\n", line);
! 317: continue;
! 318: }
! 319:
! 320: if (ln == 3) {
! 321: next_routine_flag = TRUE;
! 322: }
! 323:
! 324: trimmed_line = strdup (line);
! 325:
! 326: if (strcmp (fma_trim_string (trimmed_line), "") == 0) {
! 327:
! 328: next_routine_flag = TRUE;
! 329:
! 330: if(rtn_open == TRUE) {
! 331: fclose(rtn);
! 332:
! 333: rtn_open = FALSE;
! 334: }
! 335:
! 336: continue;
! 337: }
! 338:
! 339: if(next_routine_flag == TRUE) {
! 340:
! 341: next_routine_flag = FALSE;
! 342:
! 343: parsed_line = strtok (line, "^");
! 344:
! 345: if((!isalpha(line[0])) && (line[0] != '%')) {
! 346:
! 347: if(rtn_open == TRUE) {
! 348: fclose(rtn);
! 349: rtn_open = FALSE;
! 350: }
! 351:
! 352: continue;
! 353: }
! 354:
! 355: printf(" %s\n", parsed_line);
! 356:
! 357:
! 358: switch(line[0]) {
! 359:
! 360: case '%':
! 361: pct_loaded++;
! 362:
! 363: snprintf(roufile, PATH_MAX, "%s/%s.m", pct_rtn_path, parsed_line);
! 364: break;
! 365:
! 366: default:
! 367: usr_loaded++;
! 368:
! 369: snprintf(roufile, PATH_MAX, "%s/%s.m", usr_rtn_path, parsed_line);
! 370: break;
! 371: }
! 372:
! 373: if((file_exists(roufile) == TRUE) && (rtn_overwrite == FALSE)) {
! 374: fprintf(stdout, "fmadm: routine file '%s' already exists. Will not overwrite.\n", roufile);
! 375:
! 376: fclose (archive);
! 377:
! 378: return 1;
! 379: }
! 380:
! 381: if((rtn = fopen(roufile, "w")) == NULL) {
! 382: fprintf(stdout, "fmadm: could not open routine file '%s'.\n", roufile);
! 383:
! 384: return 1;
! 385: }
! 386: else {
! 387: rtn_open = TRUE;
! 388: }
! 389:
! 390: }
! 391: else {
! 392: if(rtn_open == TRUE) fprintf(rtn, "%s\n", line);
! 393: }
! 394:
! 395: }
! 396:
! 397: printf("\n - loaded %d user routines and %d percent routines (%d total)\n\n", usr_loaded, pct_loaded, usr_loaded + pct_loaded);
! 398:
! 399: fclose (archive);
! 400:
! 401: return 0;
! 402: }
! 403:
! 404: int fma_routines_export (int optc, char **opts)
! 405: {
! 406:
! 407: FILE *out; /* output file handle */
! 408: DIR *dir; /* namespace directory */
! 409:
! 410: struct dirent *ent;
! 411: char output_file[STRLEN];
! 412: char routine_spec[STRLEN];
! 413: char filename[STRLEN];
! 414: char *rtnname;
! 415: char *rtnext;
! 416: int i;
! 417:
! 418: int ct = 0;
! 419:
! 420:
! 421: if (optc < fma_min_args) {
! 422: fprintf (stderr, "usage: fmadm export routine <namespace> <output-file> [routine1 routine2... routineN]\n");
! 423: return 1;
! 424: }
! 425:
! 426: /* if routines aren't listed, assume we should export entire namespace */
! 427: if (optc == fma_min_args) {
! 428: strncpy (routine_spec, "*", STRLEN - 1);
! 429: }
! 430:
! 431: strncpy (output_file, opts[1], STRLEN - 1);
! 432: strncpy (routine_spec, opts[2], STRLEN - 1);
! 433:
! 434: if (file_exists (output_file) == TRUE) {
! 435: fprintf (stderr, "fmadm: output file %s already exists\n", output_file);
! 436: return 1;
! 437: }
! 438:
! 439: if ((out = fopen(output_file, "w")) == NULL) {
! 440: fprintf (stderr, "fmadm: could not open output file %s for writing\n", output_file);
! 441: return 1;
! 442: }
! 443:
! 444:
! 445: printf ("\nFreeM Routine Export\n");
! 446: printf ("--------------------\n\n");
! 447:
! 448: printf ("Namespace: %s\n", fma_namespace);
! 449: printf ("Routine Path: %s\n", fma_routine_path);
! 450: printf ("Output File: %s\n", output_file);
! 451: printf ("Routines Selected: ");
! 452:
! 453: if (optc == 2) {
! 454: printf ("[ENTIRE NAMESPACE]\n\n");
! 455: }
! 456: else {
! 457: for (i = 2; i < optc; i++) {
! 458: printf ("%s ", opts[i]);
! 459: }
! 460:
! 461: printf ("\n\n");
! 462: }
! 463:
! 464: fprintf (out, "Routines\n");
! 465:
! 466: if (optc == 2) {
! 467:
! 468: /* export entire namespace */
! 469:
! 470: if ((dir = opendir (fma_routine_path)) == NULL) {
! 471: fprintf (stderr, "fmadm: could not open routine directory %s\n", fma_routine_path);
! 472: fclose (out);
! 473: return 1;
! 474: }
! 475:
! 476: while ((ent = readdir (dir)) != NULL) {
! 477:
! 478: strncpy (filename, ent->d_name, STRLEN - 1);
! 479:
! 480: rtnname = strtok (filename, ".");
! 481: rtnext = strtok (NULL, ".");
! 482:
! 483: if (rtnext != NULL && strncmp (rtnext, "m", STRLEN - 1) == 0) {
! 484: ct += fma_do_export (out, rtnname);
! 485: }
! 486:
! 487: }
! 488:
! 489: closedir (dir);
! 490:
! 491: }
! 492: else {
! 493:
! 494: /* export only selected routines */
! 495: for (i = fma_base_opt + 1; i < optc; i++) {
! 496: ct += fma_do_export (out, opts[i]);
! 497: }
! 498:
! 499: }
! 500:
! 501: printf ("\n\n - %d routines exported\n\n", ct);
! 502:
! 503: fclose (out);
! 504:
! 505: return 0;
! 506:
! 507: }
! 508:
! 509: int fma_do_export (FILE *out, char *rtn_name)
! 510: {
! 511: FILE *in;
! 512: char rtnfile[STRLEN];
! 513: char line[FM_STR_MAX];
! 514:
! 515: snprintf (rtnfile, STRLEN - 1, "%s/%s.m", fma_routine_path, rtn_name);
! 516:
! 517: printf (" Exporting %-10s\t", rtn_name);
! 518:
! 519: if ((in = fopen (rtnfile, "r")) == NULL) {
! 520: printf ("[FAIL]\n");
! 521: return 0;
! 522: }
! 523:
! 524: fprintf (out, "\n%s\n", rtn_name);
! 525:
! 526: while (fgets (line, FM_STR_MAX, in) != NULL) {
! 527: fprintf (out, "%s", line);
! 528: }
! 529:
! 530: printf ("[OK]\n");
! 531:
! 532: fprintf (out, "\n");
! 533:
! 534: fclose (in);
! 535:
! 536: return 1;
! 537: }
! 538:
! 539: int fma_routines_create (int optc, char **opts)
! 540: {
! 541: return 0;
! 542: }
! 543:
! 544: int fma_routines_remove (int optc, char **opts)
! 545: {
! 546:
! 547: char rpath[STRLEN];
! 548: int i;
! 549: int ct = 0;
! 550: int er = 0;
! 551: int tot = 0;
! 552:
! 553: printf ("\nFreeM Routine Removal\n");
! 554: printf ("---------------------\n\n");
! 555:
! 556: printf ("Namespace: %s\n", fma_namespace);
! 557: printf ("Routine Path: %s\n\n", fma_routine_path);
! 558:
! 559: for (i = fma_base_opt; i < optc; i++) {
! 560: printf ("%-10s\t", opts[i]);
! 561:
! 562: snprintf (rpath, STRLEN - 1, "%s/%s.m", fma_routine_path, opts[i]);
! 563:
! 564: if (unlink (rpath) == -1) {
! 565: printf ("[FAIL]\n");
! 566: er++;
! 567: }
! 568: else {
! 569: printf ("[OK]\n");
! 570: ct++;
! 571: }
! 572:
! 573: tot++;
! 574:
! 575: }
! 576:
! 577: printf ("\nRemoved %d routines [%d errors/%d attempted]\n\n", ct, er, tot);
! 578:
! 579: return 0;
! 580:
! 581: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>