home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / unaxcess / part3 / udl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  15.1 KB  |  677 lines

  1. /*
  2.  * %W% %E% %U% ncoast!bsa %Z%
  3.  * %Z% Copyright (C) 1986 by Brandon S. Allbery, All Rights Reserved %Z%
  4.  */
  5.  
  6. #ifndef lint
  7. static char _SccsId[] = "%W% %E% %U% ncoast!bsa %Z%";
  8. static char _CopyRt[] = "%Z% Copyright (C) 1985 by Brandon S. Allbery %Z%";
  9. #endif  lint
  10.  
  11. #include "ua.h"
  12. #ifdef BSD
  13. #include <sys/time.h>
  14. #else  SYS3
  15. #include <time.h>
  16. #endif BSD
  17.  
  18. #define A_UPLOAD    parms.ua_auc
  19. #define A_DOWNLOAD    parms.ua_adc
  20.  
  21. #define X_UPLOAD    parms.ua_xuc
  22. #define X_DOWNLOAD    parms.ua_xdc
  23.  
  24. #define K_UPLOAD    parms.ua_kuc
  25. #define K_DOWNLOAD    parms.ua_kdc
  26.  
  27. #define LIBRARY        "library"
  28. #define DIRECTORY    "directory"
  29. #define STORAGE        "uploads"
  30. #define UPLOG        "upload-log"
  31.  
  32. #define off        0
  33. #define on        1
  34.  
  35. #define pager        __col = 0, __line = 0, __Page =
  36.  
  37. #define DIRFORMAT    "%[^ ] %*1[Ff]%*1[Ii]%*1[Ll]%*1[Ee] %[^;]; %[^ ] %*1[Bb]%*1[Yy] %[^:]: %[^\n]"
  38.  
  39. jmp_buf brchloop, fileloop;
  40. static char thisbrch[80] = "";
  41.  
  42. int __Page = on;
  43. int __line = 0;
  44. int __col = 0;
  45. int __paws = off;
  46.  
  47. char *whatis(), *pgetin(), *cpmform(), *upstr(), *today();
  48.  
  49. extern struct tm *localtime();
  50.  
  51. udl(branch)
  52. char *branch; {
  53.     int again();
  54.     int (*oldint)();
  55.     char *cp;
  56.  
  57.     if (user.u_access < A_FILES) {
  58.         puts("\nYou will not be able to upload or download files.\nYou may, however, download File Lists.");
  59.         log("File Section entered; access restricted");
  60.     }
  61.     thisbrch[0] == '\0';
  62.     for (cp = branch; *cp != '\0'; cp++)
  63.         if (*cp == ' ') {
  64.             strcpy(thisbrch, ++cp);
  65.             break;
  66.         }
  67.     oldint = signal(SIGINT, again);
  68.     setjmp(brchloop);
  69.     while (libmenu())
  70.         ;
  71.     msg("\n");
  72.     signal(SIGINT, oldint);
  73. }
  74.  
  75. again() {
  76.     signal(SIGINT, again);
  77.     pager on;
  78.     msg("\nInterrupt\n");
  79.     fflush(stdout);
  80.     log("Interrupt");
  81.     if (__paws == on) {
  82.         talk();
  83.         __paws = off;
  84.     }
  85.     longjmp(brchloop, 1);
  86. }
  87.  
  88. libmenu() {
  89.     struct direct *branch;
  90.     DIR *library;
  91.     char cmd[512], bname[512];
  92.     int (*oldsig)();
  93.     int brch_cmd();
  94.     char *desc;
  95.     
  96.     if ((library = opendir(LIBRARY)) == NULL) {
  97.         msg("The Library is closed\n");
  98.         return 0;
  99.     }
  100.     if (thisbrch[0] != '\0') {
  101.         strcpy(cmd, thisbrch);
  102.         thisbrch[0] == '\0';
  103.         goto gotbrch;
  104.     }
  105.     msg("\nThe UNaXcess File Section.  Please select one of the following\nbranches, or EXIT to leave the Library.\n\n");
  106.     while ((branch = readdir(library)) != NULL) {
  107.         if ((desc = whatis(branch->d_name, NULL)) == NULL)
  108.             continue;
  109.         msg("    %-8.8s   %s\n", upstr(branch->d_name), desc);
  110.     }
  111.     closedir(library);
  112.     msg("\nBranch: ");
  113.     if (pgetin(cmd, NULL) == NULL)
  114.         return 0;
  115.     log("Branch: %s", cmd);
  116.     if (s_cmp(cmd, "EXIT") == 0)
  117.         return 0;
  118.  
  119. gotbrch:
  120.     if (whatis(cmd, NULL) != NULL) {
  121.         library = opendir(LIBRARY);
  122.         while ((branch = readdir(library)) != NULL)
  123.             if (s_cmp(branch->d_name, cmd) == 0) {
  124.                 closedir(library);
  125.                 strcpy(bname, branch->d_name);
  126.                 oldsig = signal(SIGINT, brch_cmd);
  127.                 setjmp(fileloop);
  128.                 while (visit(bname))
  129.                     ;
  130.                 signal(SIGINT, oldsig);
  131.                 return 1;
  132.             }
  133.     }
  134.     closedir(library);
  135.     msg("There is no such branch.  If you wish to open a new branch,\nleave a message to %s.\n", parms.ua_sysop);
  136.     return 1;
  137. }
  138.  
  139. visit(branch)
  140. char *branch; {
  141.     char cmd[512];
  142.     DIR *directory;
  143.     
  144.     sprintf(cmd, "%s/%s", LIBRARY, branch);
  145.     if ((directory = opendir(cmd)) == NULL) {
  146.         msg("The %s branch is closed.\n", upstr(branch));
  147.         return 0;
  148.     }
  149.     closedir(directory);
  150.     msg("\n%s Branch\nUpload, Download, List of Files, Get File List, Exit: ", upstr(branch));
  151.     if (pgetin(cmd, NULL) == NULL)
  152.         return 0;
  153.     log("Branch cmd: %s", cmd);
  154.     switch (cmd[0]) {
  155.         case 'e':
  156.         case 'E':
  157.             return 0;
  158.         case 'U':
  159.         case 'u':
  160.             upload(branch);
  161.             break;
  162.         case 'D':
  163.         case 'd':
  164.             download(branch);
  165.             break;
  166.         case 'L':
  167.         case 'l':
  168.             filelist(branch);
  169.             break;
  170.         case 'G':
  171.         case 'g':
  172.             getlist(branch);
  173.             break;
  174.         default:
  175.             msg("Unrecognized command.\n");
  176.     }
  177.     return 1;
  178. }
  179.  
  180. brch_cmd() {
  181.     pager on;
  182.     msg("\nInterrupt\n");
  183.     log("Interrupt");
  184.     fflush(stdout);
  185.     if (__paws == on) {
  186.         talk();
  187.         __paws = off;
  188.     }
  189.     signal(SIGINT, brch_cmd);
  190.     longjmp(fileloop, 1);
  191. }
  192.  
  193. filelist(branch)
  194. char *branch; {
  195.     char path[512];
  196.     DIR *directory;
  197.     struct direct *file;
  198.     char *desc;
  199.  
  200.     sprintf(path, "%s/%s", LIBRARY, branch);
  201.     directory = opendir(path);
  202.     msg("\nFile Directory for the %s Branch:\n\n", upstr(branch));
  203.     while ((file = readdir(directory)) != NULL) {
  204.         if ((desc = whatis(branch, file->d_name)) == NULL)
  205.             continue;
  206.         msg("    %-12.12s   %s\n", cpmform(file->d_name), desc);
  207.     }
  208.     msg("\n");
  209.     closedir(directory);
  210. }
  211.  
  212. getlist(branch)
  213. char *branch; {
  214.     char path[512], listfile[30], cmd[512];
  215.     DIR *directory;
  216.     struct direct *file;
  217.     int (*oldsig)();
  218.     char *desc;
  219.     FILE *list;
  220.  
  221.     sprintf(listfile, "/tmp/cli%05d", getpid());
  222.     if ((list = fopen(listfile, "w")) == NULL) {
  223.         msg("Can't open temporary list file???\n");
  224.         exit(5);
  225.     }
  226.     msg("\nDownload file listing from the %s branch\n\nSupported transfer protocols are: Ascii, Xmodem, and Kermit.\nXmodem protocol uses checksums; CCITT CRC is not supported.\n\nEnter File Transfer Protocol (XMODEM default): ", upstr(branch));
  227.     if (pgetin(cmd, NULL) == NULL)
  228.         return;
  229.     log("List dnld mode: %s", cmd);
  230.     switch (cmd[0]) {
  231.         case 'A':
  232.         case 'a':
  233.             if (!validudl(A_DOWNLOAD)) {
  234.                 msg("\nAscii Download is not supported.\n");
  235.                 log("No Ascii");
  236.                 return;
  237.             }
  238.             sprintf(cmd, A_DOWNLOAD, listfile);
  239.             break;
  240.         case 'K':
  241.         case 'k':
  242.             if (!validudl(K_DOWNLOAD)) {
  243.                 msg("\nKermit Download is not supported.\n");
  244.                 log("No Kermit");
  245.                 return;
  246.             }
  247.             sprintf(cmd, K_DOWNLOAD, listfile);
  248.             break;
  249.         case 'X':
  250.         case 'x':
  251.             if (!validudl(X_DOWNLOAD)) {
  252.                 msg("\nXModem Download is not supported.\n");
  253.                 log("No Xmodem");
  254.                 return;
  255.             }
  256.             sprintf(cmd, X_DOWNLOAD, listfile);
  257.             break;
  258.         case '\0':
  259.             cmd[0] = 'X';
  260.             if (!validudl(X_DOWNLOAD)) {
  261.                 msg("\nXModem Download is not supported.\n");
  262.                 log("No Xmodem");
  263.                 return;
  264.             }
  265.             sprintf(cmd, X_DOWNLOAD, listfile);
  266.             break;
  267.         default:
  268.             msg("Invalid protocol designation.\n");
  269.             return;
  270.     }
  271.     sprintf(path, "%s/%s", LIBRARY, branch);
  272.     directory = opendir(path);
  273.     fprintf(list, "File Directory for the %s Branch:\r\n\r\n", upstr(branch));
  274.     while ((file = readdir(directory)) != NULL) {
  275.         if ((desc = whatis(branch, file->d_name)) == NULL)
  276.             continue;
  277.         fprintf(list, "    %-12.12s   %s\r\n", cpmform(file->d_name), desc);
  278.     }
  279.     fclose(list);
  280.     closedir(directory);
  281.     msg("You have 30 seconds to prepare for file transmission.\nPress BREAK to abort transmission.\n\n");
  282.     fflush(stdout);
  283.     sleep(30);
  284.     oldsig = signal(SIGINT, SIG_IGN);
  285.     system(cmd);
  286. #ifdef SYS3
  287.     system("stty echoe");
  288. #endif SYS3
  289.     signal(SIGINT, oldsig);
  290.     unlink(listfile);
  291. }
  292.  
  293. download(branch)
  294. char *branch; {
  295.     char path[512], filename[512], cmd[512];
  296.     DIR *directory;
  297.     struct direct *file;
  298.     int (*oldsig)();
  299.     
  300.     if (user.u_access < A_FILES) {
  301.         log("Attempted download, access denied.");
  302.         puts("You may not download files.");
  303.         return;
  304.     }
  305.     msg("\nDownload from the %s branch\n\nEnter file to download: ");
  306.     if (pgetin(filename, NULL) == NULL)
  307.         return;
  308.     log("Dnld file: %s", filename);
  309.     if (filename[0] == '.' || Index(filename, '/') != NULL) {
  310.         msg("No such file: \"%s\"\n", upstr(filename));
  311.         return;
  312.     }
  313.     if (whatis(branch, filename) != NULL) {
  314.         sprintf(path, "%s/%s", LIBRARY, branch);
  315.         directory = opendir(path);
  316.         while ((file = readdir(directory)) != NULL) {
  317.             if (s_cmp(file->d_name, filename) == 0) {
  318.                 closedir(directory);
  319.                 sprintf(path, "%s/%s/%s", LIBRARY, branch, file->d_name);
  320.                 msg("Supported transfer protocols are: Ascii, Xmodem, and Kermit.\nXmodem protocol uses checksums; CCITT CRC is not supported.\n\nEnter File Transfer Protocol (XMODEM default): ", upstr(branch));
  321.                 if (pgetin(cmd, NULL) == NULL)
  322.                     return;
  323.                 switch (cmd[0]) {
  324.                     case 'A':
  325.                     case 'a':
  326.                         if (!validudl(A_DOWNLOAD)) {
  327.                             msg("\nAscii Download is not supported.\n");
  328.                             log("No Ascii");
  329.                             return;
  330.                         }
  331.                         sprintf(cmd, A_DOWNLOAD, path);
  332.                         break;
  333.                     case 'K':
  334.                     case 'k':
  335.                         if (!validudl(K_DOWNLOAD)) {
  336.                             msg("\nKermit Download is not supported.\n");
  337.                             log("No Kermit");
  338.                             return;
  339.                         }
  340.                         sprintf(cmd, K_DOWNLOAD, path);
  341.                         break;
  342.                     case 'X':
  343.                     case 'x':
  344.                         if (!validudl(X_DOWNLOAD)) {
  345.                             msg("\nXModem Download is not supported.\n");
  346.                             log("No Xmodem");
  347.                             return;
  348.                         }
  349.                         sprintf(cmd, X_DOWNLOAD, path);
  350.                         break;
  351.                     case '\0':
  352.                         cmd[0] = 'X';
  353.                         if (!validudl(X_DOWNLOAD)) {
  354.                             msg("\nXModem Download is not supported.\n");
  355.                             log("No Xmodem");
  356.                             return;
  357.                         }
  358.                         sprintf(cmd, X_DOWNLOAD, path);
  359.                         break;
  360.                     default:
  361.                         msg("Invalid protocol designation.\n");
  362.                         return;
  363.                 }
  364.                 msg("You have 30 seconds to prepare for file transmission.\nPress BREAK to abort transmission.\n\n");
  365.                 fflush(stdout);
  366.                 sleep(30);
  367.                 oldsig = signal(SIGINT, SIG_IGN);
  368.                 system(cmd);
  369. #ifdef SYS3
  370.                 system("stty echoe");
  371. #endif SYS3
  372.                 signal(SIGINT, oldsig);
  373.                 return;
  374.             }
  375.         }
  376.         closedir(directory);
  377.     }
  378.     msg("No such file: \"%s\"\n", upstr(filename));
  379.     log("No such file");
  380. }
  381.  
  382. upload(branch)
  383. char *branch; {
  384.     char path[512], filename[512], cmd[512], desc[512];
  385.     DIR *directory;
  386.     struct direct *file;
  387.     int (*oldsig)();
  388.     FILE *logf;
  389.     
  390.     if (user.u_access < A_FILES) {
  391.         log("Attempted upload, access denied.");
  392.         puts("You may not upload files.");
  393.         return;
  394.     }
  395.     msg("\nUpload to the %s branch\n\nEnter the name to give the new file: ");
  396.     if (pgetin(filename, NULL) == NULL)
  397.         return;
  398.     log("Upld file: %s", filename);
  399.     if (filename[0] == '.' || Index(filename, '/') != NULL || Index(filename, ';') != NULL) {
  400.         msg("Invalid filename: \"%s\"\n", upstr(filename));
  401.         log("Invalid filename");
  402.         return;
  403.     }
  404.     sprintf(path, "%s/%s", STORAGE, branch);
  405.     if ((directory = opendir(path)) == NULL) {
  406.         msg("The %s has denied upload ability for this branch.\n", parms.ua_sysop);
  407.         return;
  408.     }
  409.     while ((file = readdir(directory)) != NULL) {
  410.         if (s_cmp(file->d_name, filename) == 0) {
  411.             closedir(directory);
  412.             msg("That file name is used.  Please try again with a different filename.\n");
  413.             log("File exists");
  414.             return;
  415.         }
  416.     }
  417.     closedir(directory);
  418.     msg("Enter a description for the file: ");
  419.     if (pgetin(desc, NULL) == NULL)
  420.         return;
  421.     log("Description: %s", desc);
  422.     if ((logf = fopen(UPLOG, "a")) == NULL) {
  423.         log("Error %d opening %s", errno, UPLOG);
  424.         msg("Can't log the new file.\n");
  425.         return;
  426.     }
  427.     fprintf(logf, "%s file %s; %s by %s: %s\n", branch, filename, today(), upstr(user.u_name), desc);
  428.     fclose(logf);
  429.     sprintf(path, "%s/%s/%s", STORAGE, branch, filename);
  430.     msg("Supported transfer protocols are: Ascii, Xmodem, and Kermit.\nXmodem protocol uses checksums; CCITT CRC is not supported.\n\nEnter File Transfer Protocol (XMODEM default): ", upstr(branch));
  431.     if (pgetin(cmd, NULL) == NULL)
  432.         return;
  433.     log("Upld protocol: %s", cmd);
  434.     switch (cmd[0]) {
  435.         case 'A':
  436.         case 'a':
  437.             if (!validudl(A_UPLOAD)) {
  438.                 msg("\nAscii Upload is not supported.\n");
  439.                 log("No Ascii");
  440.                 return;
  441.             }
  442.             sprintf(cmd, A_UPLOAD, path);
  443.             break;
  444.         case 'K':
  445.         case 'k':
  446.             if (!validudl(K_UPLOAD)) {
  447.                 msg("\nKermit Upload is not supported.\n");
  448.                 log("No Kermit");
  449.                 return;
  450.             }
  451.             sprintf(cmd, K_UPLOAD, path);
  452.             break;
  453.         case 'X':
  454.         case 'x':
  455.             if (!validudl(X_UPLOAD)) {
  456.                 msg("\nXModem Upload is not supported.\n");
  457.                 log("No Xmodem");
  458.                 return;
  459.             }
  460.             sprintf(cmd, X_UPLOAD, path);
  461.             break;
  462.         case '\0':
  463.             cmd[0] = 'X';
  464.             if (!validudl(X_UPLOAD)) {
  465.                 msg("\nXModem Upload is not supported.\n");
  466.                 log("No Xmodem");
  467.                 return;
  468.             }
  469.             sprintf(cmd, X_UPLOAD, path);
  470.             break;
  471.         default:
  472.             msg("Invalid protocol designation.\n");
  473.             return;
  474.     }
  475.     msg("You have 30 seconds to prepare for file transmission.\nPress BREAK to abort transmission.\n\n");
  476.     fflush(stdout);
  477.     sleep(30);
  478.     oldsig = signal(SIGINT, SIG_IGN);
  479.     system(cmd);
  480. #ifdef SYS3
  481.     system("stty echoe");
  482. #endif SYS3
  483.     signal(SIGINT, oldsig);
  484. }
  485.  
  486. /*
  487.  * The following code is snarfed from UNaXcess V1.0, primarily as a test.
  488.  * Some audacious soul may want to backport this to the rest of UA...
  489.  */
  490.  
  491. msg(argp)
  492. int *argp; {
  493.     int **ap;
  494.     char buf[BUFSIZ];
  495.     FILE prwbuf;
  496.     register int *fp;
  497.     register char *cp;
  498. #ifdef USE_PRINT
  499.     extern FILE *_pfile;
  500. #endif USE_PRINT
  501.     
  502.     ap = &argp;
  503.     ap++;
  504.     prwbuf._flag = _IOWRT|_IOSTRG;
  505.     prwbuf._cnt = 32767;
  506.     prwbuf._ptr = buf;
  507.     prwbuf._base = buf;
  508.     fp = *(ap - 1);
  509. #ifdef USE_PRINT
  510.     _pfile = &prwbuf;
  511.     _print(fp, &ap);
  512. #else  USE_PRINT
  513.     argp++;
  514.     _doprnt(fp, &argp, &prwbuf);
  515. #endif USE_PRINT
  516.     putc('\0', &prwbuf);
  517.     for (cp = buf; *cp != '\0'; cp++)
  518.         say(*cp);
  519. }
  520.  
  521. say(ch)
  522. char ch; {
  523.     ch &= 0x7f;
  524.     switch (ch) {
  525.         case '\t':
  526.             do {
  527.                 say(' ');
  528.             } while (__col % 8);
  529.             break;
  530.         case '\n':
  531.             putchar('\n');
  532.             __col = 0;
  533.             if (__Page == on && ++__line == 23) {
  534.                 paws();
  535.                 __line = 0;
  536.             }
  537.             break;
  538.         case '\177':
  539.             msg("^?");
  540.             break;
  541.         default:
  542.             if (ch < ' ') {
  543.                 say('^');
  544.                 say(ch + '@');
  545.                 return;
  546.             }
  547.             if (__col == user.u_llen - 1)
  548.                 say('\n');
  549.             putchar(ch);
  550.             __col++;
  551.     }
  552. }
  553.  
  554. paws() {
  555.     fputs("Type any key to continue. . .", stdout);
  556.     __paws = on;
  557.     silent();
  558.     getchar();
  559.     talk();
  560.     __paws = off;
  561.     fputs("\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b\b \b", stdout);
  562. }
  563.  
  564. s_cmp(s1, s2)
  565. char *s1, *s2; {
  566.     for (; *s1 != '\0' && ToLower(*s1) == ToLower(*s2); s1++, s2++)
  567.         ;
  568.     return (!(*s1 == '\0' && *s2 == '\0'));
  569. }
  570.  
  571. char *whatis(branch, file)
  572. char *branch, *file; {
  573.     static FILE *directory = NULL;
  574.     static char dent[512];
  575.     char tbr[512], tfi[512], date[512], who[512], desc[512];
  576.     
  577.     if (directory != NULL || (directory = fopen(DIRECTORY, "r")) != NULL) {
  578.         fseek(directory, 0L, 0);
  579.         while (fgets(dent, sizeof dent, directory) != NULL) {
  580.             if (dent[0] == '%' || dent[0] == '\n')
  581.                 continue;
  582.             tbr[0] = '\0';
  583.             tfi[0] = '\0';
  584.             date[0] = '\0';
  585.             who[0] = '\0';
  586.             desc[0] = '\0';
  587.             sscanf(dent, DIRFORMAT, tbr, tfi, date, who, desc);
  588.             if (s_cmp(tbr, branch) == 0) {
  589.                 if (s_cmp(tfi, (file == NULL? "branch": file)) != 0)
  590.                     continue;
  591.                 sprintf(dent, "%s [Created %s by %s]", desc, date, who);
  592.                 return dent;
  593.             }
  594.         }
  595.     }
  596.     log("No download directory");
  597.     return NULL;
  598. }
  599.  
  600. /* this is a stub-ified version of v1.0 COMND input module */
  601.  
  602. char *pgetin(str, tab)
  603. char *str;
  604. char tab[]; {
  605.     char *ch;
  606.  
  607.     fflush(stdout);
  608.     pager off;
  609.     ch = gets(str);
  610.     pager on;
  611.     if (ch == NULL) {
  612.         msg("^D\n");
  613.         log("EOF");
  614.         fflush(stdout);
  615.     }
  616.     return ch;
  617. }
  618.  
  619. char *cpmform(fn)
  620. char *fn; {
  621.     static char buf[13];
  622.     register int cnt, scnt;
  623.     
  624.     for (scnt = 0, cnt = 0; cnt < 8 && fn[cnt] != '.' && fn[cnt] != '\0'; cnt++, scnt++)
  625.         buf[scnt] = ToUpper(fn[cnt]);
  626.     while (scnt < 8)
  627.         buf[scnt++] = ' ';
  628.     buf[scnt++] = '.';
  629.     while (fn[cnt] != '.' && fn[cnt] != '\0')
  630.         cnt++;
  631.     if (fn[cnt] == '.')
  632.         cnt++;
  633.     while (scnt < 12 && fn[cnt] != '\0') {
  634.         buf[scnt++] = ToUpper(fn[cnt]);
  635.         cnt++;
  636.     }
  637.     buf[scnt] = '\0';
  638.     return buf;
  639. }
  640.  
  641. char *upstr(s)
  642. char *s; {
  643.     static char sbuf[512];
  644.     register char *cp, *dp;
  645.     
  646.     for (cp = s, dp = sbuf; *cp != '\0'; cp++, dp++)
  647.         *dp = ToUpper(*cp);
  648.     *dp = '\0';
  649.     return sbuf;
  650. }
  651.  
  652. char *today() {
  653.     long now;
  654.     struct tm *date;
  655.     static char buf[11];
  656.     
  657.     time(&now);
  658.     date = localtime(&now);
  659.     sprintf(buf, "%d/%d/%d", date->tm_mon + 1, date->tm_mday, date->tm_year);
  660.     return buf;
  661. }
  662.  
  663. validudl(cmd)
  664. char *cmd; {
  665.     if (cmd[0] == '\0')
  666.         return 0;
  667.     if (Index(cmd, '%') != RIndex(cmd, '%'))
  668.         return 0;
  669.     if (Index(cmd, '%') == (char *) 0) {
  670.         strcat(cmd, " %s");
  671.         return 1;
  672.     }
  673.     if (*(Index(cmd, '%') + 1) != 's')
  674.         return 0;
  675.     return 1;
  676. }
  677.