home *** CD-ROM | disk | FTP | other *** search
/ linuxmafia.com 2016 / linuxmafia.com.tar / linuxmafia.com / pub / linux / backup / star-1.3.1.tar.gz / star-1.3.1.tar / star-1.3.1 / star / longnames.c < prev    next >
C/C++ Source or Header  |  2000-11-09  |  8KB  |  342 lines

  1. /* @(#)longnames.c    1.23 00/11/09 Copyright 1993, 1995 J. Schilling */
  2. #ifndef lint
  3. static    char sccsid[] =
  4.     "@(#)longnames.c    1.23 00/11/09 Copyright 1993, 1995 J. Schilling";
  5. #endif
  6. /*
  7.  *    Handle filenames that cannot fit into a single
  8.  *    string of 100 charecters
  9.  *
  10.  *    Copyright (c) 1993, 1995 J. Schilling
  11.  */
  12. /*
  13.  * This program is free software; you can redistribute it and/or modify
  14.  * it under the terms of the GNU General Public License as published by
  15.  * the Free Software Foundation; either version 2, or (at your option)
  16.  * any later version.
  17.  *
  18.  * This program 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 General Public License for more details.
  22.  *
  23.  * You should have received a copy of the GNU General Public License
  24.  * along with this program; see the file COPYING.  If not, write to
  25.  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  26.  */
  27.  
  28. #include <mconfig.h>
  29. #include "star.h"
  30. #include "props.h"
  31. #include "table.h"
  32. #include <standard.h>
  33. #include <strdefs.h>
  34. #include <schily.h>
  35. #include "starsubs.h"
  36.  
  37. typedef struct {
  38.     char    *m_name;
  39.     int    m_size;
  40.     int    m_add;
  41. } move_t;
  42.  
  43. LOCAL    void    enametoolong    __PR((char* name, int len, int maxlen));
  44. LOCAL    char*    split_posix_name __PR((char* name, int namlen, int add));
  45. EXPORT    BOOL    name_to_tcb    __PR((FINFO * info, TCB * ptb));
  46. EXPORT    void    tcb_to_name    __PR((TCB * ptb, FINFO * info));
  47. EXPORT    void    tcb_undo_split    __PR((TCB * ptb, FINFO * info));
  48. LOCAL    int    move_from_name    __PR((move_t * move, char* p, int amount));
  49. LOCAL    int    move_to_name    __PR((move_t * move, char* p, int amount));
  50. EXPORT    int    tcb_to_longname    __PR((TCB * ptb, FINFO * info));
  51. EXPORT    void    write_longnames    __PR((FINFO * info));
  52. LOCAL    void    put_longname    __PR((FINFO * info,
  53.                     char* name, int namelen, char* tname,
  54.                             Ulong  xftype));
  55.  
  56. LOCAL void
  57. enametoolong(name, len, maxlen)
  58.     char    *name;
  59.     int    len;
  60.     int    maxlen;
  61. {
  62.     xstats.s_toolong++;
  63.     errmsgno(EX_BAD, "%s: Name too long (%d > %d chars)\n",
  64.                             name, len, maxlen);
  65. }
  66.  
  67.  
  68. LOCAL char *
  69. split_posix_name(name, namlen, add)
  70.     char    *name;
  71.     int    namlen;
  72.     int    add;
  73. {
  74.     register char    *low;
  75.     register char    *high;
  76.  
  77.     if (namlen+add > props.pr_maxprefix+1+props.pr_maxsname) {
  78.         /*
  79.          * Cannot split
  80.          */
  81.         if (props.pr_maxnamelen <= props.pr_maxsname) /* No longnames*/
  82.             enametoolong(name, namlen+add,
  83.                 props.pr_maxprefix+1+props.pr_maxsname);
  84.         return (NULL);
  85.     }
  86.     low = &name[namlen+add - props.pr_maxsname];
  87.     if (--low < name)
  88.         low = name;
  89.     high = &name[props.pr_maxprefix>namlen ? namlen:props.pr_maxprefix];
  90.  
  91. #ifdef    DEBUG
  92. error("low: %d:%s high: %d:'%c',%s\n",
  93.             strlen(low), low, strlen(high), *high, high);
  94. #endif
  95.     high++;
  96.     while (--high >= low)
  97.         if (*high == '/')
  98.             break;
  99.     if (high < low) {
  100.         if (props.pr_maxnamelen <= props.pr_maxsname) {
  101.             xstats.s_toolong++;
  102.             errmsgno(EX_BAD, "%s: Name too long (cannot split)\n",
  103.                                     name);
  104.         }
  105.         return (NULL);
  106.     }
  107. #ifdef    DEBUG
  108. error("solved: add: %d prefix: %d suffix: %d\n",
  109.             add, high-name, strlen(high+1)+add);
  110. #endif
  111.     return (high);
  112. }
  113.  
  114. /*
  115.  * Es ist sichergestelt, da▀ namelen >= 1 ist.
  116.  */
  117. EXPORT BOOL
  118. name_to_tcb(info, ptb)
  119.     FINFO    *info;
  120.     TCB    *ptb;
  121. {
  122.     char    *name = info->f_name;
  123.     int    namelen = info->f_namelen;
  124.     int    add = 0;
  125.     char    *np = NULL;
  126.  
  127.     if (namelen == 0)
  128.         raisecond("name_to_tcb: namelen", 0L);
  129.  
  130.     if (is_dir(info) && name[namelen-1] != '/')
  131.         add++;
  132.  
  133.     if ((namelen+add) <= props.pr_maxsname) {    /* Fits in shortname */
  134.         if (add)
  135.             strcatl(ptb->dbuf.t_name, name, "/", (char *)NULL);
  136.         else
  137.             strcpy(ptb->dbuf.t_name, name);
  138.         return (TRUE);
  139.     }
  140.  
  141.     if (props.pr_nflags & PR_POSIX_SPLIT)
  142.         np = split_posix_name(name, namelen, add);
  143.     if (np == NULL) {
  144.         /*
  145.          * cannot split
  146.          */
  147.         if (namelen+add <= props.pr_maxnamelen) {
  148.             info->f_flags |= F_LONGNAME;
  149.             if (add)
  150.                 info->f_flags |= F_ADDSLASH;
  151.             strncpy(ptb->dbuf.t_name, name, props.pr_maxsname);
  152.             return (TRUE);
  153.         } else {
  154.             enametoolong(name, namelen+add, props.pr_maxnamelen);
  155.             return (FALSE);
  156.         }
  157.     }
  158.  
  159.     if (add)
  160.         strcatl(ptb->dbuf.t_name, &np[1], "/", (char *)NULL);
  161.     else
  162.         strcpy(ptb->dbuf.t_name, &np[1]);
  163.     strncpy(ptb->dbuf.t_prefix, name, np - name);
  164.     info->f_flags |= F_SPLIT_NAME;
  165.     return (TRUE);
  166. }
  167.  
  168. EXPORT void
  169. tcb_to_name(ptb, info)
  170.     TCB    *ptb;
  171.     FINFO    *info;
  172. {
  173.     /*
  174.      * Name has already been set up because it is a very long name or
  175.      * because it has been setup from somwhere else.
  176.      * We have nothing to do.
  177.      */
  178.     if (info->f_flags & (F_LONGNAME|F_HAS_NAME))
  179.         return;
  180.  
  181.     if (props.pr_nflags & PR_POSIX_SPLIT) {
  182.         strcatl(info->f_name, ptb->dbuf.t_prefix,
  183.                         *ptb->dbuf.t_prefix?"/":"",
  184.                         ptb->dbuf.t_name, NULL);
  185.     } else {
  186.         strcpy(info->f_name, ptb->dbuf.t_name);
  187.     }
  188. }
  189.  
  190. EXPORT void
  191. tcb_undo_split(ptb, info)
  192.     TCB    *ptb;
  193.     FINFO    *info;
  194. {
  195.     fillbytes(ptb->dbuf.t_name, NAMSIZ, '\0');
  196.     fillbytes(ptb->dbuf.t_prefix, props.pr_maxprefix, '\0');
  197.  
  198.     info->f_flags &= ~F_SPLIT_NAME;
  199.     info->f_flags |= F_LONGNAME;
  200.  
  201.     strncpy(ptb->dbuf.t_name, info->f_name, props.pr_maxsname);
  202. }
  203.  
  204. #define    vp_move_from_name ((int(*)__PR((void *, char *, int)))move_from_name)
  205.  
  206. /*
  207.  * Move name from archive.
  208.  */
  209. LOCAL int
  210. move_from_name(move, p, amount)
  211.     move_t    *move;
  212.     char    *p;
  213.     int    amount;
  214. {
  215.     movebytes(p, move->m_name, amount);
  216.     move->m_name += amount;
  217.     move->m_name[0] = '\0';
  218.     return (amount);
  219. }
  220.  
  221. #define    vp_move_to_name    ((int(*)__PR((void *, char *, int)))move_to_name)
  222.  
  223. /*
  224.  * Move name to archive.
  225.  */
  226. LOCAL int
  227. move_to_name(move, p, amount)
  228.     move_t    *move;
  229.     char    *p;
  230.     int    amount;
  231. {
  232.     if (amount > move->m_size)
  233.         amount = move->m_size;
  234.     movebytes(move->m_name, p, amount);
  235.     move->m_name += amount;
  236.     move->m_size -= amount;
  237.     if (move->m_add) {
  238.         if (move->m_size == 1) {
  239.             p[amount-1] = '/';
  240.         } else if (move->m_size == 0) {
  241.             if (amount > 1)
  242.                 p[amount-2] = '/';
  243.             p[amount-1] = '\0';
  244.         }
  245.     }
  246.     return (amount);
  247. }
  248.  
  249. /*
  250.  * A bad idea to do this here!
  251.  * We have to set up a more generalized pool of namebuffers wich are allocated
  252.  * on an actual MAX_PATH base.
  253.  */
  254. char    longlinkname[PATH_MAX+1];
  255.  
  256. EXPORT int
  257. tcb_to_longname(ptb, info)
  258.     register TCB    *ptb;
  259.     register FINFO    *info;
  260. {
  261.     move_t    move;
  262.  
  263.     /*
  264.      * File size is strlen of name
  265.      */
  266.     astoo(ptb->dbuf.t_size, &info->f_size);
  267.     info->f_rsize = info->f_size;
  268.     if (info->f_size > PATH_MAX) {
  269.         xstats.s_toolong++;
  270.         errmsgno(EX_BAD, "Long name too long (%ld) ignored.\n",
  271.                             info->f_size);
  272.         void_file(info);
  273.         return (get_tcb(ptb));
  274.     }
  275.     if (ptb->dbuf.t_linkflag == LF_LONGNAME) {
  276.         info->f_namelen = info->f_size -1;
  277.         info->f_flags |= F_LONGNAME;
  278.         move.m_name = info->f_name;
  279.     } else {
  280.         info->f_lname = longlinkname;
  281.         info->f_lnamelen = info->f_size -1;
  282.         info->f_flags |= F_LONGLINK;
  283.         move.m_name = info->f_lname;
  284.     }
  285.     if (xt_file(info, vp_move_from_name, &move, 0, "moving long name") < 0)
  286.         die(EX_BAD);
  287.  
  288.     return (get_tcb(ptb));
  289. }
  290.  
  291. EXPORT void
  292. write_longnames(info)
  293.     register FINFO    *info;
  294. {
  295.     /*
  296.      * XXX Should test for F_LONGNAME & F_FLONGLINK
  297.      */
  298.     if (info->f_namelen > props.pr_maxsname) {
  299.         put_longname(info, info->f_name, info->f_namelen+1,
  300.                         "././@LongName", XT_LONGNAME);
  301.     }
  302.     if (info->f_lnamelen > props.pr_maxslname) {
  303.         put_longname(info, info->f_lname, info->f_lnamelen+1,
  304.                         "././@LongLink", XT_LONGLINK);
  305.     }
  306. }
  307.  
  308. LOCAL void
  309. put_longname(info, name, namelen, tname, xftype)
  310.     FINFO    *info;
  311.     char    *name;
  312.     int    namelen;
  313.     char    *tname;
  314.     Ulong    xftype;
  315. {
  316.     FINFO    finfo;
  317.     TCB    *ptb;
  318.     move_t    move;
  319.  
  320.     fillbytes((char *)&finfo, sizeof(finfo), '\0');
  321.  
  322.     ptb = (TCB *)get_block();
  323.     finfo.f_flags |= F_TCB_BUF;
  324.     fillbytes((char *)ptb, TBLOCK, '\0');
  325.  
  326.     strcpy(ptb->dbuf.t_name, tname);
  327.  
  328.     move.m_add = 0;
  329.     if ((info->f_flags & F_ADDSLASH) != 0 && xftype == XT_LONGNAME) {
  330.         move.m_add = 1;
  331.         namelen++;
  332.     }
  333.     finfo.f_rsize = finfo.f_size = namelen;
  334.     finfo.f_xftype = xftype;
  335.     info_to_tcb(&finfo, ptb);
  336.     write_tcb(ptb, &finfo);
  337.  
  338.     move.m_name = name;
  339.     move.m_size = finfo.f_size;
  340.     cr_file(&finfo, vp_move_to_name, &move, 0, "moving long name");
  341. }
  342.