home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / disk utilities / backup / backup_restore / backup_src_v3.20.lha / CmdFile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-30  |  13.1 KB  |  628 lines

  1. /* CmdFile.c */
  2. /* 23 Mar 1996 13:05:51 */
  3.  
  4. #ifndef    BACKUP_INCLUDE
  5. #include "IncludeAll.c"
  6. #endif
  7. #include "Backup.h"
  8. #include "FileSelect.h"
  9. #include "Backup_proto.h"
  10. #include "BackupStrings.h"
  11.  
  12.  
  13. /* aus Revision.c */
  14. extern SHORT Version;
  15.  
  16.  
  17. FILE *aktCmdFile = NULL;    /* fp für Kommandofile */
  18. char __far CmdFileName[FMSIZE];    /* Name des Kommandofile */
  19.  
  20. static char __far LastCmdFileName[FMSIZE];
  21.  
  22. static short CheckFSEntry(struct FSDir *Dir, struct FSDirEntry *FSe,
  23.         struct BackupOptions *Opt, FILE *NewCmdFile);
  24. static char *ProcessIncludeFile(char *line, struct FSDir **Dir, struct BackupOptions *Opt);
  25.  
  26. static unsigned short LineNo = 0;
  27.  
  28.  
  29. /* liefert TRUE wenn Ok */
  30. BOOL OpenCmdFile(const char *name)
  31. {
  32.     ASSERT_VALID(name);
  33.     LineNo = 0;
  34.     stccpy(LastCmdFileName, name, sizeof(LastCmdFileName));
  35.     aktCmdFile = fopen(name, "r");
  36.     if (aktCmdFile == NULL)
  37.         {
  38.         alarm(GetString(MSG_CANNOTOPEN_CMDFILE),
  39.             ShortFileName(NurName(name), 60), GetIoErrText() );
  40.         return FALSE;
  41.         }
  42.     return TRUE;
  43. }
  44.  
  45.  
  46. void CloseCmdFile(void)
  47. {
  48.     if (aktCmdFile)
  49.         {
  50.         fclose(aktCmdFile);
  51.         aktCmdFile = NULL;
  52.         }
  53. }
  54.  
  55.  
  56. void WriteCmdFile(struct Window *Win, char *FileName, short withIcon,
  57.         struct BackupOptions *Opt)
  58. {
  59.     struct FSDir *Dir;
  60.     char FileMode[] = "w", CmdLine[FMSIZE+50] = "";
  61.     FILE *NewCmdFile;
  62.     short erg, error = 0;
  63.  
  64.     ASSERT_VALID(Win);
  65.     ASSERT_VALID(FileName);
  66.     ASSERT_VALID(Opt);
  67.  
  68.     stccpy(LastCmdFileName, FileName, sizeof(LastCmdFileName));
  69.  
  70.     if (access(FileName, 0) == 0)
  71.         {
  72.         /* Kommandofile gibt es schon */
  73.         erg = AskReplace(Win, GetString(MSG_CMDFILE_EXISTS),
  74.             ShortFileName(NurName(FileName), 30));
  75.  
  76.         if (erg == *GetString(MSG_ABORT_SHORT))
  77.             {
  78.             /* Abbruch */
  79.             return;
  80.             }
  81.         else if (erg == *GetString(MSG_APPEND_SHORT))
  82.             {
  83.             /* Append */
  84.             *FileMode = 'a';
  85.             }
  86.         else if (erg == *GetString(MSG_REPLACE_SHORT))
  87.             {
  88.             /* Replace */
  89.             *FileMode = 'w';
  90.             }
  91.         }
  92.  
  93.     NewCmdFile = fopen(FileName, FileMode);
  94.     if (NewCmdFile == NULL)
  95.         {
  96.         alarm(GetString(MSG_CANNOTOPEN_CMDFILE), NurName(FileName),
  97.                 GetIoErrText() );
  98.         return;
  99.         }
  100.  
  101.     fprintf(NewCmdFile, GetString(MSG_CMDFILE_HEADER), Version/100, Version % 100);
  102.  
  103.     if (aktCmdFile)
  104.         {
  105.         strcpy(CmdLine, "@");
  106.         strcat(CmdLine, CmdFileName);
  107.         }
  108.     else
  109.         {
  110.         static const size_t OptOffsets[] =
  111.             {
  112.             offsetof(struct BackupOptions, bo_ProtFileName),
  113.             offsetof(struct BackupOptions, bo_KeepProtFile),
  114.             offsetof(struct BackupOptions, bo_UseGrepPattern),
  115.             offsetof(struct BackupOptions, bo_IncludeSubDirs),
  116.             offsetof(struct BackupOptions, bo_Append),
  117.             offsetof(struct BackupOptions, bo_SaveSoftLinks),
  118.             offsetof(struct BackupOptions, bo_SaveHardLinks),
  119.             offsetof(struct BackupOptions, bo_UseArc),
  120.             offsetof(struct BackupOptions, bo_SetArc),
  121.             offsetof(struct BackupOptions, bo_FirstDate),
  122.             offsetof(struct BackupOptions, bo_LastDate),
  123.             offsetof(struct BackupOptions, bo_ProtFile),
  124.             offsetof(struct BackupOptions, bo_Verify),
  125.             offsetof(struct BackupOptions, bo_Compress),
  126.             offsetof(struct BackupOptions, bo_Preview),
  127.             offsetof(struct BackupOptions, bo_IncludeFile),
  128.             offsetof(struct BackupOptions, bo_ExcludeFile),
  129.             offsetof(struct BackupOptions, bo_UseHardwareCompression)
  130.             };
  131.         char *lp;
  132.         size_t MaxLength;
  133.         short m, n;
  134.  
  135.         lp = CmdLine;
  136.         MaxLength = sizeof(CmdLine) - 1;
  137.  
  138.         for (m=0; m<sizeof(OptOffsets)/sizeof(OptOffsets[0]); m++)
  139.             {
  140.             size_t Length;
  141.  
  142.             GetToolTypeText(Opt, OptOffsets[m], lp, MaxLength);
  143.             if (*lp)
  144.                 {
  145.                 strcat(lp, " ");
  146.  
  147.                 Length = strlen(lp);
  148.                 if (strlen(CmdLine) < 75)
  149.                     {
  150.                     lp += Length;
  151.                     MaxLength -= Length;
  152.                     }
  153.                 else
  154.                     {
  155.                     // Neue Zeile anfangen
  156.                     fprintf(NewCmdFile, "%s+\n", CmdLine);
  157.                     lp = CmdLine;
  158.                     MaxLength = sizeof(CmdLine) - 1;
  159.                     *CmdLine = '\0';
  160.                     }
  161.                 }
  162.             }
  163.  
  164.         if (strlen(CmdLine) > 0)
  165.             fprintf(NewCmdFile, "%s+\n", CmdLine);
  166.  
  167.         for (erg=1, n=0; erg && n<Opt->bo_FSDirCount; n++)
  168.             {
  169.             Dir = Opt->bo_FSDirList[n];
  170.             if (Dir->fsd_SelectCount > 0 && ManualSelectCount(Dir))
  171.                 {
  172.                 fprintf(NewCmdFile, "-ID\"%s\"+\n", Dir->fsd_Name);
  173.  
  174.                 for (m=0; erg && m<Dir->fsd_DirCount; m++)
  175.                     erg = CheckFSEntry(Dir, Dir->fsd_EntryList[m], Opt, NewCmdFile);
  176.                 }
  177.             }
  178.         }
  179.  
  180.     if (erg)
  181.         erg = fprintf(NewCmdFile, "\n");
  182.  
  183.     if (erg == 0)
  184.         {
  185.         error = 1;
  186.         alarm(GetString(MSG_ERRORWRITING_CMDFILE), NurName(FileName),
  187.             GetIoErrText() );
  188.         }
  189.  
  190.     fclose(NewCmdFile);
  191.  
  192.     if (!error && withIcon)
  193.         {
  194.         if (!SaveListIcon(Opt, FileName))
  195.             {
  196.             alarm(GetString(MSG_ERRORCREATING_CMDFILE_ICON),
  197.                 NurName(FileName), GetIoErrText() );
  198.             }
  199.         }
  200. }
  201.  
  202.  
  203. static short CheckFSEntry(struct FSDir *Dir, struct FSDirEntry *FSe,
  204.         struct BackupOptions *Opt, FILE *NewCmdFile)
  205. {
  206.     char hilf[FMSIZE];
  207.     short erg = 1;
  208.     char *Name;
  209.  
  210.     ASSERT_VALID(FSe);
  211.     ASSERT_VALID(Opt);
  212.     ASSERT_VALID(NewCmdFile);
  213.  
  214.     if (FSe->fse_Selected == ST_Selected)
  215.         {
  216.         switch (FSe->fse_Typ)
  217.             {
  218.         case File:
  219.             erg = fprintf(NewCmdFile, "-IF\"%s\"+\n", FSe->fse_Name);
  220.             break;
  221.         case SoftLinkDir:
  222.             erg = fprintf(NewCmdFile, "-ILd\"%s\"+\n", FSe->fse_Name);
  223.             break;
  224.         case SoftLinkFile:
  225.             erg = fprintf(NewCmdFile, "-ILf\"%s\"+\n", FSe->fse_Name);
  226.             break;
  227.         case HardLinkDir:
  228.             erg = fprintf(NewCmdFile, "-ILD\"%s\"+\n", FSe->fse_Name);
  229.             break;
  230.         case HardLinkFile:
  231.             erg = fprintf(NewCmdFile, "-ILF\"%s\"+\n", FSe->fse_Name);
  232.             break;
  233.         case Device:
  234.             erg = fprintf(NewCmdFile, "-IP\"%s\"+\n", FSe->fse_Name);    // Partition
  235.             break;
  236.         case Directory:
  237.         case Assign:
  238.         case Volume:
  239.             Name = ConcatDirName(Dir->fsd_Name, FSe->fse_Name);
  240.  
  241.             if (ManualSelectCount(SearchFSDir(Name)) == 0 &&
  242.                     ManualSelectCount(FSe->fse_Contents) == 0)
  243.                 {
  244.                 /* Subdirectory komplett einschließen
  245.                    nur wenn nicht schon irgendwo manuell etwas
  246.                    eingetragen wurde */
  247.                 strmfn(hilf, NULL, FSe->fse_Name,
  248.                         Opt->bo_IncludeFile.RawName, NULL);
  249.                 erg = fprintf(NewCmdFile, "-IS\"%s\"+\n", hilf);
  250.                 }
  251.             free(Name);
  252.             break;
  253.             }
  254.         }
  255.  
  256.     return erg;
  257. }
  258.  
  259.  
  260. /* einen Eintrag aus dem Kommandofile lesen und auswerten */
  261. char *ReadCmdFile(struct BackupOptions *Opt, BOOL InitFS)
  262. {
  263.     static char line[FMSIZE], name[FMSIZE];
  264.     static char filepath[FMSIZE];
  265.     char *p, lastc;
  266.     struct FSDir *Dir = NULL;
  267.     BOOL first = TRUE;
  268.  
  269.     ASSERT_VALID(Opt);
  270.  
  271.     do    {
  272.         p = fgets(line, sizeof(line)-1, aktCmdFile);    /* 1 Zeile lesen */
  273.         if (p == NULL)                /* EOF erreicht */
  274.             return NULL;
  275.  
  276.         /* Default-Einstellung nur wenn kein EOF */
  277.         if (first)
  278.             {
  279.             /* Diese Switches können in jedem Eintrag anders gesetzt werden */
  280.             Opt->bo_IncludeSubDirs = 1;    /* Default: mit Subdirectories */
  281.             Opt->bo_UseArc = Ignore;    /* Default: Archiv-Flag ist egal */
  282.             Opt->bo_SetArc = Set;        /* default: Archiv-Flag setzen */
  283.             Opt->bo_UseFirstDate = 0;    /* default: nicht nach Datum prüfen */
  284.             Opt->bo_UseLastDate = 0;    /* default: nicht nach Datum prüfen */
  285.             Opt->bo_UseGrepPattern = 1;
  286.  
  287.             if (InitFS)
  288.                 InitFileSelect(Opt);
  289.  
  290.             first = FALSE;
  291.             }
  292.  
  293.         LineNo++;
  294.  
  295.         if (*p == '%')
  296.             {
  297.             lastc = '+';
  298.             continue;        /* Kommentar */
  299.             }
  300.  
  301.         if (p[strlen(p)-1] == '\n')
  302.             p[strlen(p)-1] = '\0';
  303.  
  304.         lastc = p[strlen(p)-1];
  305.         if (lastc == '+')
  306.             p[strlen(p)-1] = '\0';
  307.  
  308.         while (p && *p)
  309.             {
  310.             p = stpblk(p);        /* Führende Leerzeichen überlesen */
  311.             switch (*p)
  312.                 {
  313.             case '-':
  314.             case '/':
  315.                 if (p[1] == 'I')
  316.                     p = ProcessIncludeFile(++p, &Dir, Opt);
  317.                 else
  318.                     {
  319.                     char ErrorLine[129];
  320.  
  321.                     sprintf(ErrorLine, GetString(MSG_CMDFILE_LINE),
  322.                         NurName(LastCmdFileName), LineNo);    // Fehler-Kopf vorbereiten für processOption()
  323.  
  324.                     p = processOption(++p, ErrorLine, Opt);
  325.                     }
  326.                 break;
  327.             default:
  328.                 p = ReadString(name, p, sizeof(name)-1);
  329.  
  330.             //    stcgfn(Opt->bo_IncludeFile.RawName, name);    /* Get file node */
  331.             //    stcgfp(filepath, name);                /* Get file path */
  332.  
  333.                 if (*name)
  334.                     {
  335.                     // hier muß eine ToolType-Einstellung stehen
  336.                     if (!CheckLineForToolType(name, Opt))
  337.                         p = NULL;        // <name> konnte nicht identifiziert werden!
  338.                     }
  339.                 break;
  340.                 }
  341.             }
  342.  
  343.         if (p == NULL)
  344.             {
  345.             alarm(GetString(MSG_SYNTAXERROR_IN_CMDFILE),
  346.                 NurName(LastCmdFileName), LineNo, line);
  347.             myabort(0);
  348.             }
  349.         } while (lastc == '+');
  350.  
  351.     InitSearchPattern(Opt);
  352.  
  353.     return filepath;
  354. }
  355.  
  356.  
  357. static char *ProcessIncludeFile(char *line, struct FSDir **Dir,
  358.         struct BackupOptions *Opt)
  359. {
  360.     static char FName[FMSIZE], FName2[FMSIZE];
  361.     struct FSDirEntry *FSe;
  362.     char LinkType;
  363.  
  364.     ASSERT_VALID(line);
  365.     ASSERT_VALID(Dir);
  366.     ASSERT_VALID(Opt);
  367.  
  368.     switch (*++line)
  369.         {
  370.     case 'D':        /* Directory */
  371.         line = ReadString(FName, ++line, sizeof(FName)-1);
  372.         *Dir = CreateFSDir(FName, Opt);
  373.         if (*Dir == NULL)
  374.             return NULL;
  375.         break;
  376.     case 'L':        /* SoftLink */
  377.         if (*Dir == NULL)
  378.             return NULL;
  379.  
  380.         LinkType = *++line;
  381.  
  382.         line = ReadString(FName, ++line, sizeof(FName)-1);
  383.         switch (LinkType)
  384.             {
  385.         case 'D':
  386.             FSe = AddFSEntry(*Dir, FName, HardLinkDir);
  387.             break;
  388.         case 'd':
  389.             FSe = AddFSEntry(*Dir, FName, SoftLinkDir);
  390.             break;
  391.         case 'F':
  392.             FSe = AddFSEntry(*Dir, FName, HardLinkFile);
  393.             break;
  394.         case 'f':
  395.             FSe = AddFSEntry(*Dir, FName, SoftLinkFile);
  396.             break;
  397.             }
  398.         SelectFSEntry(*Dir, FSe);
  399.         break;
  400.     case 'P':        /* Partition */
  401.         if (*Dir == NULL)
  402.             return NULL;
  403.  
  404.         line = ReadString(FName, ++line, sizeof(FName)-1);
  405.         if (FindPartition(FName))
  406.             {
  407.             FSe = AddFSEntry(*Dir, FName, Device);
  408.             SelectFSEntry(*Dir, FSe);
  409.             }
  410.         else
  411.             alarm(GetString(MSG_PARTITION_NOTFOUND), FName);
  412.         break;
  413.     case 'F':        /* File */
  414.         if (*Dir == NULL)
  415.             return NULL;
  416.  
  417.         line = ReadString(FName, ++line, sizeof(FName)-1);
  418.         FSe = AddFSEntry(*Dir, FName, File);
  419.         SelectFSEntry(*Dir, FSe);
  420.         break;
  421.     case 'S':        /* Subdirectory */
  422.         if (*Dir == NULL)
  423.             return NULL;
  424.  
  425.         line = ReadString(FName, ++line, sizeof(FName)-1);
  426.         stcgfp(FName2, FName);        /* Get file path */
  427.         FSe = AddFSEntry(*Dir, FName2, Directory);
  428.         SelectFSEntry(*Dir, FSe);
  429.  
  430.         stcgfn(Opt->bo_IncludeFile.RawName, FName);        /* Get file node */
  431.         Opt->bo_IncludeFile.isParsed = 0;
  432.         break;
  433.         }
  434.  
  435.     return line;
  436. }
  437.  
  438.  
  439. char *processOption(const char *opt, const char *ErrPrefix, struct BackupOptions *BOpt)
  440. {
  441.     char c;
  442.  
  443.     ASSERT_VALID(opt);
  444.     ASSERT_VALID(ErrPrefix);
  445.     ASSERT_VALID(BOpt);
  446.  
  447.     while (*opt)
  448.         {
  449.         switch (c = *opt)
  450.             {
  451.         case 'a':            /* Anhängen an altes Backup */
  452.             BOpt->bo_Append = 1;
  453.             break;
  454.         case 'b':            /* nur Files jünger als ..Datum */
  455.             BOpt->bo_UseLastDate = (BOpt->bo_LastDate = ReadDate(++opt)) ? 1 : 0;
  456.             while (*opt && !isspace(*opt))
  457.                 opt++;        /* Datum überlesen */
  458.             opt--;
  459.             break;
  460.         case 'c':
  461.             if (!isspace(opt[1]))
  462.                 {
  463.                 char *p = BOpt->XPKPackerName;
  464.  
  465.                 ++opt;
  466.                 BOpt->bo_Compress = COMPRESS_XPK;
  467.                 while (*opt && !isspace(*opt))
  468.                     *p++ = *opt++;
  469.                 opt--;
  470.                 }
  471.             else
  472.                 BOpt->bo_Compress = COMPRESS_INTERNAL;    /* Files komprimieren */
  473.             break;
  474. #ifdef TAPEDEBUG
  475.         case 'd':
  476.             TapeDebugLevel = atoi(++opt);
  477.             while (isdigit(*opt))
  478.                 opt++;
  479.             break;
  480. #endif
  481.         case 'e':
  482.             BOpt->bo_Preview = TRUE;
  483.             break;
  484.         case 'f':            /* Archiv-Flag nicht setzen */
  485.             switch (opt[1])
  486.                 {
  487.             case '1':
  488.                 opt++;
  489.                 BOpt->bo_SetArc = Set;
  490.                 break;
  491.             case '2':
  492.                 opt++;
  493.                 BOpt->bo_SetArc = Reset;
  494.                 break;
  495.             case '0':
  496.                 opt++;
  497.             default:
  498.                 BOpt->bo_SetArc = Ignore;
  499.                 break;
  500.                 }
  501.             break;
  502.         case 'g':            /* Laufwerke ohne TD_GETGEOMETRY */
  503.             opt = ReadString(BOpt->bo_DrivesWithoutGeometry, ++opt,
  504.                 sizeof(BOpt->bo_DrivesWithoutGeometry));
  505.             break;
  506.         case 'k':
  507.             switch (opt[1])
  508.                 {
  509.             case '1':
  510.                 BOpt->bo_ProtFile = PT_Binary;
  511.                 opt++;
  512.                 break;
  513.             case '2':
  514.                 BOpt->bo_ProtFile = PT_ASCII;
  515.                 opt++;
  516.                 break;
  517.             default:
  518.                 BOpt->bo_ProtFile = PT_ASCII;
  519.                 break;
  520.                 }
  521.             break;
  522.         case 'l':            /* Links */
  523.             switch (opt[1])
  524.                 {
  525.             case 'h':
  526.                 opt++;
  527.                 switch (opt[1])
  528.                     {
  529.                 case '0':
  530.                     BOpt->bo_SaveHardLinks = 0;
  531.                     opt++;
  532.                     break;
  533.                 case '1':
  534.                     BOpt->bo_SaveHardLinks = 1;
  535.                     opt++;
  536.                     break;
  537.                     }
  538.                 break;
  539.             case 's':        /* SoftLinks */
  540.                 opt++;
  541.             default:
  542.                 switch (opt[1])
  543.                     {
  544.                 case '0':
  545.                     BOpt->bo_SaveSoftLinks = 0;
  546.                     opt++;
  547.                     break;
  548.                 case '1':
  549.                     BOpt->bo_SaveSoftLinks = 1;
  550.                     opt++;
  551.                     break;
  552.                     }
  553.                 break;
  554.                 }
  555.             break;
  556.         case 'n':            /* nur geänderte Files */
  557.             switch (opt[1])
  558.                 {
  559.             case '0':
  560.                 BOpt->bo_UseArc = Ignore;
  561.                 opt++;
  562.                 break;
  563.             case '1':
  564.                 BOpt->bo_UseArc = Set;
  565.                 opt++;
  566.                 break;
  567.             case '2':
  568.                 opt++;
  569.             default:
  570.                 BOpt->bo_UseArc = Reset;
  571.                 break;
  572.                 }
  573.             break;
  574.         case 'o':            /* ohne Subdirectories */
  575.             BOpt->bo_IncludeSubDirs = FALSE;
  576.             break;
  577.         case 'p':
  578.             BOpt->bo_Verify = TRUE;    /* mit Verify */
  579.             break;
  580.         case 'v':            /* nur Files älter als ..Datum */
  581.             BOpt->bo_UseFirstDate = (BOpt->bo_FirstDate = ReadDate(++opt)) ? 1 : 0;
  582.             while (*opt && !isspace(*opt))
  583.                 opt++;        /* Datum überlesen */
  584.             opt--;
  585.             break;
  586.         case 'w':            /* DOS oder einfache WildCards */
  587.             switch (opt[1])
  588.                 {
  589.             case '0':
  590.                 BOpt->bo_UseGrepPattern = FALSE;
  591.                 opt++;
  592.                 break;
  593.             case '1':
  594.                 BOpt->bo_UseGrepPattern = TRUE;
  595.                 opt++;
  596.                 break;
  597.                 }
  598.             break;
  599.         case 'x':            /* Exclude File Pattern */
  600.             opt = ReadString(BOpt->bo_ExcludeFile.RawName, ++opt,
  601.                 sizeof(BOpt->bo_ExcludeFile.RawName));
  602.             break;
  603.  
  604.         case '?':
  605.             CallHelp(0L, 0);
  606.             myabort(0);
  607.             break;
  608.  
  609.         case '-':            /* Beginn einer neuen Option */
  610.         case '/':
  611.             break;
  612.         case ' ':
  613.         case '\t':
  614.         case '\n':
  615.             while (isspace(*opt))
  616.                 opt++;
  617.             break;
  618.         default:
  619.             alarm(GetString(MSG_INVALID_OPTION), ErrPrefix, opt);
  620.             myabort(0);
  621.             }
  622.         if (*opt)
  623.             opt++;
  624.         }
  625.  
  626.     return opt;
  627. }
  628.