home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume22 / nn6.4 / part15 / save.c < prev   
Encoding:
C/C++ Source or Header  |  1990-06-07  |  16.3 KB  |  712 lines

  1. /*
  2.  *    (c) Copyright 1990, Kim Fabricius Storm.  All rights reserved.
  3.  *
  4.  *    Save (or print) articles
  5.  */
  6.  
  7. #include <signal.h>
  8. #include <errno.h>
  9. #include "config.h"
  10. #include "term.h"
  11. #include "keymap.h"
  12. #include "news.h"
  13.  
  14. export char *default_save_file = "+$F";
  15. export int suggest_save_file = 1;
  16. export char *unshar_header_file = "Unshar.Headers";
  17. export int  use_mail_folders = 0;
  18. export int  use_mmdf_folders = 0;
  19. export int  save_report = 1;
  20. export int  quick_save = 0;
  21. export int  conf_append = 0;
  22. export int  conf_create = 1;
  23.  
  24. export char *save_counter_format = "%d";    /* format of save counter */
  25. export int  save_counter_offset = 0;
  26.  
  27. export char printer[FILENAME] = DEFAULT_PRINTER;
  28. export int edit_print_command = 1;
  29.  
  30. export char patch_command[FILENAME] = "patch -p0";
  31. export int edit_patch_command = 1;
  32.  
  33. export char unshar_command[FILENAME] = SHELL;
  34. export int edit_unshar_command = 0;
  35.  
  36. extern int file_completion();
  37.  
  38. import char *temp_file;
  39. import int  shell_restrictions;
  40. import char delayed_msg[];
  41.  
  42. import int rot13_active;
  43.  
  44. static int save_mode;
  45. static char *unshar_cmd;
  46.  
  47. #define    HEADER_HANDLING    0x0f    /* what should we do with the header */
  48.  
  49. #define NO_HEADER    0    /* save without a header */
  50. #define    FULL_HEADER    1    /* save with full header */
  51. #define SHORT_HEADER    2    /* save with partial header */
  52. #define    SHORT_HEADER_DG    3    /* save with partial header (digest) */
  53.  
  54.  
  55. #define    SEPARATE_FILES    0x0100    /* save as separate files */
  56. #define UNIQUE_FILES    0x0200    /* save in unique files */
  57. #define    FILE_IS_NEW    0x0400    /* this is a new file */
  58. #define APPEND_ARTNUM    0x0800    /* append article number to file name */
  59. #define    IS_PIPE        0x1000    /* output is on pipe */
  60. #define    DO_UNSHAR    0x2000    /* unshar article (or patch) */
  61. #define    DO_PATCH    0x4000    /* patch article */
  62. #define    DO_DECODE    0x8000    /* uudecode article */
  63.  
  64. /* open modes for open_news_article for the various HEADER_HANDLINGs */
  65.  
  66. static int open_mode[] = {
  67.     SKIP_HEADER,
  68.     0,
  69.     FILL_NEWS_HEADER | SKIP_HEADER,
  70.     FILL_DIGEST_HEADER | SKIP_HEADER
  71. };
  72.  
  73. static FILE *save_file;            /* output stream for saved files */
  74. static char *save_name;            /* save file name */
  75.  
  76. static int uniq_counter;        /* separate files counter */
  77. static char uniq_format[FILENAME];     /* sprintf format for '*' expansion */
  78.  
  79. static char last_dir[FILENAME] = "";
  80.  
  81. /*
  82.  * return pointer to first path name component, that does not exist
  83.  */
  84.  
  85. static char *ckdir_path(name)
  86. char *name;
  87. {
  88.     char *slash;
  89.     char *component;
  90.  
  91.     component = name;
  92.  
  93.     while (slash = strchr(component, '/')) {
  94.     if (slash == component) {
  95.         /*  ...//...  */
  96.         component++;
  97.         continue;
  98.     }
  99.     *slash = NUL;
  100.     if (file_exist(name, "drx")) {
  101.         *slash++ = '/';
  102.         component = slash;
  103.         continue;
  104.     }
  105.     if (file_exist(name, (char *)NULL)) {
  106.         *slash = '/';
  107.         return NULL;
  108.     }
  109.     *slash = '/';
  110.     break;
  111.     }
  112.     return component;
  113. }
  114.  
  115. /*
  116.  * create directories in path name, starting from start
  117.  */
  118.  
  119. static mkdirs_in_path(name, start)
  120. char *name, *start;
  121. {
  122.     char *slash;
  123.     char *component;
  124.  
  125.     component = start;
  126.  
  127.     while (slash = strchr(component, '/')) {
  128.     if (slash == component) {
  129.         /*  ...//...  */
  130.         component++;
  131.         continue;
  132.     }
  133.     *slash = NUL;
  134.     if (mkdir(name, 0755)) {
  135.         msg("Cannot make %s/", name);
  136.         *slash = '/';
  137.         return 0;
  138.     }
  139.     *slash++ = '/';
  140.     component = slash;
  141.     }
  142.     return 1;
  143. }
  144.  
  145. char *init_save(command, mode_textp)
  146. char command;
  147. char **mode_textp;
  148. {
  149.     char *mode_text;
  150.     static char last_input[FILENAME] = "";
  151.     static char name_buf[512];    /* buffer for file name & command expansion */
  152.     char *start, *last, *np;
  153.     char *ckdir_path();
  154.  
  155.     uniq_counter = 0;
  156.  
  157.     switch (command) {
  158.  
  159.      case K_SAVE_FULL_HEADER:
  160.     save_mode = FULL_HEADER;
  161.     mode_text = "Save";
  162.     goto cont_save;
  163.  
  164.      case K_SAVE_SHORT_HEADER:
  165.     save_mode = SHORT_HEADER;
  166.     mode_text = "Output";
  167.     goto cont_save;
  168.  
  169.      case K_SAVE_NO_HEADER:
  170.     save_mode = NO_HEADER;
  171.     mode_text = "Write";
  172.  
  173.      cont_save:
  174.     if (quick_save && (current_group->group_flag & G_FOLDER) == 0) {
  175.         if (current_group->save_file)
  176.         save_name = current_group->save_file;
  177.         else
  178.         save_name = default_save_file;
  179.         strcpy(last_input, save_name);
  180.         save_name = last_input;
  181.     } else {
  182.         prompt("\1%s on\1 (+~|) ", mode_text);
  183.  
  184.         save_name = current_group->save_file;
  185.         if (save_name == NULL && suggest_save_file)
  186.         save_name = default_save_file;
  187.         if (save_name != NULL) {
  188.         if (!expand_file_name(name_buf, save_name, 2)) return NULL;
  189.         save_name = name_buf;
  190.         }
  191.  
  192.         save_name = get_s(last_input, save_name, NONE, file_completion);
  193.         if (save_name == NULL || *save_name == NUL) return NULL;
  194.  
  195.         if (save_name[1] == NUL && save_name[0] == '+')
  196.         save_name = default_save_file;
  197.         else
  198.         if (current_group->save_file == NULL ||
  199.             strcmp(save_name, current_group->save_file))
  200.             strcpy(last_input, save_name);
  201.     }
  202.  
  203.     if (*save_name == '|') {
  204.         if (shell_restrictions) {
  205.         msg("Restricted operation - pipes not allowed");
  206.         return NULL;
  207.         }
  208.         mode_text = "Pipe";
  209.         save_name++;
  210.         save_mode |= IS_PIPE;
  211.         if (*save_name == '|') {
  212.         save_mode |= SEPARATE_FILES;
  213.         save_name++;
  214.         }
  215.     }
  216.  
  217.     if (!expand_file_name(name_buf, save_name, (save_mode & IS_PIPE) ? 11 : 3))
  218.         return NULL;
  219.     save_name = name_buf;
  220.  
  221.     if ((save_mode & IS_PIPE) == 0) {
  222.         np = strrchr(save_name, '*');
  223.         if (np != NULL) {
  224.         *np = NUL;
  225.         sprintf(uniq_format, "%s%s%s",
  226.             save_name, save_counter_format, np + 1);
  227.         *np = '*';
  228.         save_mode |= SEPARATE_FILES | UNIQUE_FILES;
  229.         } else {
  230.         np = strrchr(save_name, '$');
  231.         if (np != NULL && np[1] == 'N') {
  232.             if (current_group->group_flag & G_FOLDER) {
  233.             msg("$N is not defined in a folder");
  234.             return NULL;
  235.             }
  236.             *np = NUL;
  237.             sprintf(uniq_format, "%s%%ld%s", save_name, np + 2);
  238.             *np = '$';
  239.             save_mode |= SEPARATE_FILES | APPEND_ARTNUM;
  240.         }
  241.         }
  242.     }
  243.     break;
  244.  
  245.      case K_UUDECODE:
  246.     save_mode = NO_HEADER | DO_UNSHAR | DO_DECODE;
  247.     mode_text = "Decode";
  248.     goto unshar1;
  249.  
  250.      case K_PATCH:
  251.     save_mode = NO_HEADER | SEPARATE_FILES | DO_UNSHAR | DO_PATCH;
  252.     mode_text = "Patch";
  253.     if (!shell_restrictions && edit_patch_command) {
  254.         prompt("\1Patch command:\1 ");
  255.         save_name = get_s(NONE, patch_command, NONE, NULL_FCT);
  256.         if (save_name == NULL || *save_name == NUL) return NULL;
  257.         strcpy(patch_command, save_name);
  258.     }
  259.     unshar_cmd = patch_command;
  260.     goto unshar1;
  261.  
  262.      case K_UNSHAR:
  263.     save_mode = NO_HEADER | SEPARATE_FILES | DO_UNSHAR;
  264.     mode_text = "Unshar";
  265.     if (!shell_restrictions && edit_unshar_command) {
  266.         prompt("\1Unshar command:\1 ");
  267.         save_name = get_s(NONE, unshar_command, NONE, NULL_FCT);
  268.         if (save_name == NULL || *save_name == NUL) return NULL;
  269.         strcpy(unshar_command, save_name);
  270.     }
  271.     unshar_cmd = unshar_command;
  272.  
  273.      unshar1:
  274.     prompt("\1%s Directory:\1 ", mode_text);
  275.     save_name = current_group->save_file;
  276.     if (save_name != NULL) {
  277.         if (!expand_file_name(name_buf, save_name, 10)) return NULL;
  278.         save_name = name_buf;
  279.     }
  280.  
  281.     save_name = get_s(last_dir, save_name, NONE, file_completion);
  282.     if (save_name == NULL || *save_name == NUL) return NULL;
  283.     strcpy(last_dir, save_name);
  284.     if (!expand_file_name(name_buf, save_name, 1))
  285.         return NULL;
  286.     save_name = name_buf;
  287.     break;
  288.  
  289.      case K_PRINT:
  290.     save_mode = SHORT_HEADER | IS_PIPE;
  291.  
  292.     if (!shell_restrictions && edit_print_command) {
  293.         prompt("\1Print command:\1 ");
  294.         save_name = get_s(NONE, printer, NONE, NULL_FCT);
  295.         if (save_name == NULL || *save_name == NUL) return NULL;
  296.         strcpy(printer, save_name);
  297.     }
  298.     if (!expand_file_name(name_buf, printer, 1))
  299.         return NULL;
  300.     save_name = name_buf;
  301.     mode_text = "Print";
  302.     break;
  303.  
  304.      default:
  305.     msg("Illegal save command: %d", command);
  306.     return NULL;
  307.     }
  308.  
  309.     if (save_name == NULL) return NULL;
  310.  
  311.     if (!(save_mode & IS_PIPE)) {
  312.     if (file_exist(save_name, (save_mode & DO_UNSHAR) ? "wd" : "wf")) {
  313.         if (save_mode & DO_UNSHAR) {
  314.         int len = strlen(save_name);
  315.         if (save_name[len - 1] != '/')
  316.             strcpy(save_name + len, "/");
  317.         } else
  318.         if (conf_append) {
  319.             printf("\rAppend to: %s ? ", save_name);
  320.             clrline();
  321.             if (!yes(0)) return NULL;
  322.         }
  323.     } else {
  324.         if (errno != ENOENT) {
  325.         msg("Cannot access %s", save_name);
  326.         return NULL;
  327.         }
  328.  
  329.         if (save_mode & DO_UNSHAR) {
  330.         int len = strlen(save_name);
  331.         if (save_name[len - 1] != '/')
  332.             strcpy(save_name + len, "/");
  333.         }
  334.  
  335.         start = ckdir_path(save_name);
  336.         if (start == NULL) {
  337.         msg("No permission");
  338.         return NULL;
  339.         }
  340.  
  341.         last = strrchr(start, '/');
  342.         /* last != NULL => non-existing directories */
  343.  
  344.         if (conf_create && (!(save_mode & SEPARATE_FILES) || last)) {
  345.         printf("\rCreate ");
  346.         for (np = save_name; *np; np++) {
  347.             if (np == start) putchar('\"');
  348.             putchar(*np);
  349.             if ((save_mode & SEPARATE_FILES) && np == last) break;
  350.         }
  351.         printf("\" ?");
  352.         clrline();
  353.         if (yes(last != NULL) <= 0) return NULL;
  354.         }
  355.  
  356.         if (last && !mkdirs_in_path(save_name, start))
  357.         return NULL;
  358.     }
  359.     }
  360.  
  361.     if (mode_textp) *mode_textp = mode_text;
  362.  
  363.     save_mode |= FILE_IS_NEW;    /* so save() will open it */
  364.  
  365.     if (save_mode & DO_DECODE) {
  366.     uud_start(save_name);
  367.     save_mode &= ~DO_UNSHAR;
  368.     }
  369.  
  370.     return save_name;
  371. }
  372.  
  373.  
  374. save(ah)
  375. article_header *ah;
  376. {
  377.     register FILE *art;
  378.     register c, lcount, mode;
  379.     news_header_buffer hdrbuf;
  380.     int was_raw = 0, set_visual = 0;
  381.     char copybuf[FILENAME * 4], uniqbuf[FILENAME];
  382.  
  383.     if (ah->a_group) init_group(ah->a_group);
  384.  
  385.     mode = save_mode & HEADER_HANDLING;
  386.     if (mode == SHORT_HEADER && ah->flag & A_DIGEST)
  387.     mode = SHORT_HEADER_DG;
  388.  
  389.     art = open_news_article(ah, open_mode[mode], hdrbuf, (char *)NULL);
  390.     if (art == NULL) {
  391.     msg("Cannot read %s", group_path_name);
  392.     return 0;
  393.     }
  394.  
  395.     if (save_mode & DO_DECODE) {
  396.     save_file = NULL;
  397.     c = uudecode(ah, art);
  398.     fclose(art);
  399.     return (c < 0) ? 0 : 1;
  400.     }
  401.  
  402.     if (save_mode & UNIQUE_FILES) {
  403.     uniqbuf[0] = NUL;
  404.     do {
  405.         strcpy(copybuf, uniqbuf);
  406.         uniq_counter++;
  407.         sprintf(uniqbuf, uniq_format, uniq_counter + save_counter_offset);
  408.         if (strcmp(uniqbuf, copybuf) == 0) {
  409.         msg("save-counter \"%s\" does not generate unique file names",
  410.             save_counter_format);
  411.         goto fatal;
  412.         }
  413.     } while (file_exist(uniqbuf, (char *)NULL));
  414.     save_name = uniqbuf;
  415.     save_mode |= FILE_IS_NEW;
  416.     } else
  417.     if (save_mode & APPEND_ARTNUM) {
  418.         sprintf(uniqbuf, uniq_format, (long)(ah->a_number));
  419.         save_name = uniqbuf;
  420.     }
  421.  
  422.     if (save_mode & FILE_IS_NEW) {
  423.     if (save_mode & (IS_PIPE | DO_UNSHAR)) {
  424.         set_visual = 1;
  425.         was_raw = visual_off();
  426.     }
  427.  
  428.     if (save_mode & IS_PIPE) {
  429.         if ((save_file = popen(save_name, "w")) == NULL) {
  430.         msg("Cannot pipe to %s", save_name);
  431.         goto fatal;
  432.         }
  433.     } else
  434.     if (save_mode & DO_UNSHAR) {
  435.         if ((save_mode & DO_PATCH) == 0) {
  436.         if (!unshar_position(art))
  437.             goto fatal;
  438.         if (unshar_header_file)
  439.             store_header(ah, art, save_name, unshar_header_file);
  440.         }
  441.  
  442.         new_temp_file();
  443.         sprintf(copybuf,
  444.             "cd %s && { %s 2>&1 ; } | tee %s ; cat %s >> %s.Result ; rm %s",
  445.             save_name != NULL ? save_name : ".", unshar_cmd,
  446.             temp_file, temp_file,
  447.             (save_mode & DO_PATCH) ? "Patch" : "Unshar",
  448.             temp_file);
  449.  
  450.         save_file = popen(copybuf, "w");
  451.         if (save_file == NULL) {
  452.         msg("Cannot exec: '%s'", copybuf);
  453.         goto fatal;
  454.         }
  455.         printf("\r\n%s %s\r\n",
  456.            save_mode & DO_PATCH ? "PATCHING FROM" : "UNPACKING",
  457.            ah->subject ? ah->subject : "ARTICLE"); fl;
  458.     } else {
  459.         if ((save_file = open_file(save_name, OPEN_APPEND)) == NULL) {
  460.         msg("Cannot write %s", save_name);
  461.         fclose(art);
  462.         return 0;
  463.         }
  464.         if (ftell(save_file) != (off_t)0)
  465.         save_mode &= ~FILE_IS_NEW;
  466.     }
  467.     }
  468.  
  469.     clrline();
  470.     s_pipe = 0;
  471.  
  472.     if (mode != NO_HEADER)
  473.     mailbox_format(save_file, 1);
  474.  
  475.     if (mode == FULL_HEADER) {
  476.     off_t cnt = ah->fpos - ah->hpos;
  477.     while (--cnt >= 0) {
  478.         if ((c = getc(art)) == EOF) break;
  479.         putc(c, save_file);
  480.     }
  481.     } else
  482.     if (mode == SHORT_HEADER) {
  483.     if (news.ng_from)
  484.         fprintf(save_file, "From: %s\n", news.ng_from);
  485.     if (news.ng_date)
  486.         fprintf(save_file, "Date: %s\n", news.ng_date);
  487.     if (news.ng_subj)
  488.         fprintf(save_file, "Subject: %s\n", news.ng_subj);
  489.     fputc(NL, save_file);
  490.     } else
  491.     if (mode == SHORT_HEADER_DG) {
  492.     if (digest.dg_from)
  493.         fprintf(save_file, "From: %s\n", digest.dg_from);
  494.     if (digest.dg_date)
  495.         fprintf(save_file, "Date: %s\n", digest.dg_date);
  496.     if (digest.dg_subj)
  497.         fprintf(save_file, "Subject: %s\n", digest.dg_subj);
  498.     fputc(NL, save_file);
  499.     }
  500.  
  501.     fflush(save_file);
  502.     if (s_pipe) goto broken_pipe;
  503.  
  504.     mode = mode != NO_HEADER && (save_mode & (IS_PIPE | DO_UNSHAR)) == 0;
  505.  
  506.     lcount = 0;
  507.     while (ftell(art) < ah->lpos && fgets(copybuf, 512, art)) {
  508.     lcount++;
  509.     if (rot13_active) rot13_line(copybuf);
  510.     if (mode && is_header_line(copybuf))
  511.         fputc('~', save_file);
  512.     fputs(copybuf, save_file);
  513.     if (s_pipe) goto broken_pipe;
  514.     }
  515.  
  516.     if (mode != NO_HEADER)
  517.     lcount += mailbox_format(save_file, 0);
  518.  
  519. broken_pipe:
  520.     fclose(art);
  521.  
  522.     if (save_mode & DO_UNSHAR) {
  523.     if ((c = pclose(save_file)) != 0)
  524.         sprintf(delayed_msg, "Save command failed; exit = %d", c);
  525.     save_file = NULL;
  526.     } else {
  527.     if (s_pipe)
  528.         msg("Command did not read complete article!");
  529.     else
  530.         if (save_report)
  531.         msg((save_mode & IS_PIPE)     ? "%s: %d lines piped" :
  532.         (save_mode & FILE_IS_NEW) ? "%s created: %d lines written" :
  533.         "%s: %d lines appended", save_name, lcount);
  534.  
  535.     if (s_pipe || (save_mode & SEPARATE_FILES)) {
  536.         if (end_save() == 0) return 0;
  537.     } else
  538.         save_mode &= ~FILE_IS_NEW;
  539.     }
  540.  
  541. #ifdef MAIL_READING
  542.     if (mail_auto_delete && (save_mode & IS_PIPE) == 0)
  543.     if (current_group->group_flag & G_MAILBOX)
  544.         if (ah->attr != A_CANCEL)
  545.         fcancel(ah);
  546. #endif
  547.     if (set_visual) visual_on();
  548.     if (was_raw) raw();
  549.  
  550.     ah->flag |= A_ST_FILED;
  551.  
  552.     return !s_pipe || (save_mode & SEPARATE_FILES);
  553.  
  554.  fatal:
  555.     if (set_visual) visual_on();
  556.     if (was_raw) raw();
  557.     fclose(art);
  558.     return 0;
  559. }
  560.  
  561.  
  562. end_save()
  563. {
  564.     int c;
  565.     FILE *sf;
  566.     sf = save_file;
  567.     save_file = NULL;
  568.  
  569.     if (sf) {
  570.     if (save_mode & (IS_PIPE | DO_UNSHAR)) {
  571.         if ((c = pclose(sf)) != 0) {
  572.         if (c >= 256) c >>= 8;    /* HACK */
  573.         sprintf(delayed_msg, "Save command failed; exit = %d", c);
  574.         return 0;
  575.         }
  576.     } else
  577.         fclose(sf);
  578.     }
  579.  
  580.     if (save_mode & DO_DECODE) {
  581.     uud_end();
  582.     }
  583.     if (save_mode & DO_UNSHAR)
  584.     sprintf(delayed_msg, "Output is saved in %s/%s.Result",
  585.         save_name != NULL ? save_name : ".",
  586.         (save_mode & DO_PATCH) ? "Patch" : "Unshar");
  587.     return 1;
  588. }
  589.  
  590. store_header(ah, f, dir, file)
  591. article_header *ah;
  592. FILE *f;
  593. char *dir, *file;
  594. {
  595.     register int c;
  596.     off_t endpos;
  597.     FILE *h;
  598.  
  599.     if (dir != (char *)NULL && file[0] != '/')
  600.     file = relative(dir, file);
  601.     if ((h = open_file(file, OPEN_APPEND)) == NULL) {
  602.     msg("Cannot open %s", file);
  603.     return;
  604.     }
  605.     fseek(h, (off_t)0, 2);
  606.     if (!use_mmdf_folders && ftell(h) > 0) putc(NL, h);  /* just in case */
  607.     mailbox_format(h, 1);
  608.     endpos = ftell(f) - ah->hpos;
  609.     fseek(f, ah->hpos, 0);
  610.     while (--endpos >= 0 && (c = getc(f)) != EOF)
  611.     putc(c, h);
  612.  
  613.     mailbox_format(h, 0);
  614.     fclose(h);
  615. }
  616.  
  617. mailbox_format(f, top)
  618. FILE *f;
  619. int top;
  620. {
  621.     time_t now;
  622.     char *ctime();
  623.  
  624.     if (use_mmdf_folders) {
  625.     fprintf(f, "\001\001\001\001\n");
  626.     return 0;
  627.     }
  628.  
  629.     if (top == 0) {
  630.     fputc(NL, f);
  631.     return 1;
  632.     }
  633.  
  634.     if (use_mail_folders) {
  635.     now = cur_time();
  636.     fprintf(f, "From %s %s",
  637.         current_group->group_name, ctime(&now));
  638.     return 1;
  639.     }
  640.  
  641.     return 0;
  642. }
  643.  
  644. char *run_mkdir(dir, name_buf)
  645. char *dir, *name_buf;
  646. {
  647.     if (dir == NULL) {
  648.     prompt("\1Directory: \1");
  649.     dir = get_s(last_dir, NONE, NONE, file_completion);
  650.     if (dir == NULL || *dir == NUL) return NULL;
  651.     strcpy(last_dir, dir);
  652.     }
  653.  
  654.     if (*dir == '+' || *dir == '~') {
  655.     if (!expand_file_name(name_buf, dir, 1))
  656.         return NULL;
  657.     dir = name_buf;
  658.     }
  659.  
  660.     if (file_exist(dir, (char *)NULL)) {
  661.     msg("Directory %s already exists", dir);
  662.     return NULL;
  663.     }
  664.  
  665.     if (mkdir(dir, 0755)) {
  666.     msg("Cannot make %s", dir);
  667.     return NULL;
  668.     }
  669.  
  670.     return dir;
  671. }
  672.  
  673.  
  674. change_dir(dir, in_init)
  675. char *dir;
  676. int in_init;
  677. {
  678.     char dir_buf[FILENAME];
  679.  
  680.     if (dir == NULL) {
  681.     prompt("\1Directory: \1");
  682.     dir = get_s(last_dir, NONE, NONE, file_completion);
  683.     }
  684.  
  685.     if (dir == NULL || *dir == NUL) return 0;
  686.  
  687.     strcpy(last_dir, dir);
  688.  
  689.     if (*dir == '+' || *dir == '~') {
  690.     if (!expand_file_name(dir_buf, dir, 1)) return in_init;
  691.     dir = dir_buf;
  692.     }
  693.  
  694.     if (chdir(dir) == 0) {
  695.     if (!in_init) msg("Directory: %s", dir);
  696.     return 0;
  697.     }
  698.  
  699.     if (in_init) return 1;
  700.  
  701.     if (errno == EACCES)
  702.     msg("Cannot access directory %s", dir);
  703.     else {
  704.     /* should ask and create directory here */
  705.     msg("Directory not found: %s", dir);
  706.     }
  707.  
  708.     return 0;
  709. }
  710.  
  711.  
  712.