j0h

bashMod_cd.def

j0h
Feb 7th, 2026
193
0
Never
8
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 19.45 KB | None | 0 0
  1. This file is cd.def, from which is created cd.c.  It implements the
  2. builtins "cd" and "pwd" in Bash.
  3.  
  4. Copyright (C) 1987-2024 Free Software Foundation, Inc.
  5.  
  6. This file is part of GNU Bash, the Bourne Again SHell.
  7.  
  8. Bash is free software: you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation, either version 3 of the License, or
  11. (at your option) any later version.
  12.  
  13. Bash is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with Bash.  If not, see <http://www.gnu.org/licenses/>.
  20.  
  21. $PRODUCES cd.c
  22. #include <config.h>
  23.  
  24. #if defined (HAVE_UNISTD_H)
  25. #  ifdef _MINIX
  26. #    include <sys/types.h>
  27. #  endif
  28. #  include <unistd.h>
  29. #endif
  30.  
  31. #include "../bashtypes.h"
  32. #include "posixdir.h"
  33. #include "posixstat.h"
  34. #if defined (HAVE_SYS_PARAM_H)
  35. #include <sys/param.h>
  36. #endif
  37. #include <fcntl.h>
  38.  
  39. #include <stdio.h>
  40.  
  41. #include "../bashansi.h"
  42. #include "../bashintl.h"
  43.  
  44. #include <errno.h>
  45. #include <tilde/tilde.h>
  46.  
  47. #include "../shell.h"
  48. #include "../flags.h"
  49. #include "maxpath.h"
  50. #include "common.h"
  51. #include "bashgetopt.h"
  52.  
  53. #if !defined (errno)
  54. extern int errno;
  55. #endif /* !errno */
  56.  
  57. extern const char * const bash_getcwd_errstr;
  58.  
  59. static int bindpwd (int);
  60. static int setpwd (char *);
  61. static char *resetpwd (char *);
  62. static int change_to_directory (char *, int, int);
  63.  
  64. static int cdxattr (char *, char **);
  65. static void resetxattr (void);
  66.  
  67. /* Change this to 1 to get cd spelling correction by default. */
  68. int cdspelling = 0;
  69.  
  70. int cdable_vars;
  71.  
  72. static int eflag;   /* file scope so bindpwd() can see it */
  73. static int xattrflag;   /* O_XATTR support for openat */
  74. static int xattrfd = -1;
  75.  
  76. $BUILTIN cd
  77. $FUNCTION cd_builtin
  78. $SHORT_DOC cd [-L|[-P [-e]]] [-@] [dir]
  79. Change the shell working directory.
  80.  
  81. Change the current directory to DIR.  The default DIR is the value of the
  82. HOME shell variable. If DIR is "-", it is converted to $OLDPWD.
  83. If DIR is "-N" where N is a number, go up N directories in the hierarchy.
  84. "-0" does nothing, "-1" is equivalent to "-" (go to previous directory).
  85.  
  86. The variable CDPATH defines the search path for the directory containing
  87. DIR.  Alternative directory names in CDPATH are separated by a colon (:).
  88. A null directory name is the same as the current directory.  If DIR begins
  89. with a slash (/), then CDPATH is not used.
  90.  
  91. If the directory is not found, and the shell option `cdable_vars' is set,
  92. the word is assumed to be  a variable name.  If that variable has a value,
  93. its value is used for DIR.
  94.  
  95. Options:
  96.   -L    force symbolic links to be followed: resolve symbolic
  97.         links in DIR after processing instances of `..'
  98.   -P    use the physical directory structure without following
  99.         symbolic links: resolve symbolic links in DIR before
  100.         processing instances of `..'
  101.   -e    if the -P option is supplied, and the current working
  102.         directory cannot be determined successfully, exit with
  103.         a non-zero status
  104. #if defined (O_XATTR)
  105.   -@    on systems that support it, present a file with extended
  106.         attributes as a directory containing the file attributes
  107. #endif
  108.  
  109. The default is to follow symbolic links, as if `-L' were specified.
  110. `..' is processed by removing the immediately previous pathname component
  111. back to a slash or the beginning of DIR.
  112.  
  113. Exit Status:
  114. Returns 0 if the directory is changed, and if $PWD is set successfully when
  115. -P is used; non-zero otherwise.
  116. $END
  117.  
  118. /* Just set $PWD, don't change OLDPWD.  Used by `pwd -P' in posix mode. */
  119. static int
  120. setpwd (char *dirname)
  121. {
  122.  int old_anm;
  123.  SHELL_VAR *tvar;
  124.  
  125.  old_anm = array_needs_making;
  126.  tvar = bind_variable ("PWD", dirname ? dirname : "", 0);
  127.  if (tvar && readonly_p (tvar))
  128.    return EXECUTION_FAILURE;
  129.  if (tvar && old_anm == 0 && array_needs_making && exported_p (tvar))
  130.    {
  131.      update_export_env_inplace ("PWD=", 4, dirname ? dirname : "");
  132.      array_needs_making = 0;
  133.    }
  134.  return EXECUTION_SUCCESS;
  135. }
  136.  
  137. static int
  138. bindpwd (int no_symlinks)
  139. {
  140.  char *dirname, *pwdvar;
  141.  int old_anm, r, canon_failed;
  142.  SHELL_VAR *tvar;
  143.  
  144.  r = sh_chkwrite (EXECUTION_SUCCESS);
  145.  
  146. #define tcwd the_current_working_directory
  147.  dirname = tcwd ? (no_symlinks ? sh_physpath (tcwd, 0) : tcwd)
  148.          : get_working_directory ("cd");
  149. #undef tcwd
  150.  
  151.  /* If canonicalization fails, reset dirname to the_current_working_directory */
  152.  canon_failed = 0;
  153.  if (dirname == 0)
  154.    {
  155.      canon_failed = 1;
  156.      dirname = the_current_working_directory;
  157.    }
  158.  
  159.  old_anm = array_needs_making;
  160.  pwdvar = get_string_value ("PWD");
  161.  
  162.  tvar = bind_variable ("OLDPWD", pwdvar, 0);
  163.  if (tvar == 0 || readonly_p (tvar))
  164.    r = EXECUTION_FAILURE;
  165.  else if (old_anm == 0 && array_needs_making && exported_p (tvar))
  166.    {
  167.      update_export_env_inplace ("OLDPWD=", 7, pwdvar);
  168.      array_needs_making = 0;
  169.    }
  170.  
  171.  if (setpwd (dirname) == EXECUTION_FAILURE)
  172.    r = EXECUTION_FAILURE;
  173.  if (canon_failed && eflag)
  174.    r = EXECUTION_FAILURE;
  175.  
  176.  if (dirname && dirname != the_current_working_directory)
  177.    free (dirname);
  178.  
  179.  return (r);
  180. }
  181.  
  182. /* Call get_working_directory to reset the value of
  183.   the_current_working_directory () */
  184. static char *
  185. resetpwd (char *caller)
  186. {
  187.  char *tdir;
  188.      
  189.  FREE (the_current_working_directory);
  190.  the_current_working_directory = (char *)NULL;
  191.  tdir = get_working_directory (caller);
  192.  return (tdir);
  193. }
  194.  
  195. /* return new constructed directory name in *NDIRP */
  196. static int
  197. cdxattr (char *dir, char **ndirp)
  198. {
  199. #if defined (O_XATTR)
  200.  int apfd, fd, r, e;
  201.   char buf[11+40+40];   /* construct new `fake' path for pwd */
  202.  
  203.   apfd = openat (AT_FDCWD, dir, O_RDONLY|O_NONBLOCK);
  204.   if (apfd < 0)
  205.     return -1;
  206.   fd = openat (apfd, ".", O_XATTR);
  207.   e = errno;
  208.   close (apfd);     /* ignore close error for now */
  209.   errno = e;
  210.   if (fd < 0)
  211.     return -1;
  212.   r = fchdir (fd);  /* assume fchdir exists everywhere with O_XATTR */
  213.   if (r < 0)
  214.     {
  215.       close (fd);
  216.       return -1;
  217.     }
  218.   /* NFSv4 and ZFS extended attribute directories do not have names which are
  219.      visible in the standard Unix directory tree structure.  To ensure we have
  220.      a valid name for $PWD, we synthesize one under /proc, but to keep that
  221.      path valid, we need to keep the file descriptor open as long as we are in
  222.      this directory.  This imposes a certain structure on /proc. */
  223.   if (ndirp)
  224.     {
  225.       sprintf (buf, "/proc/%d/fd/%d", getpid(), fd);
  226.       *ndirp = savestring (buf);
  227.     }
  228.  
  229.   if (xattrfd >= 0)
  230.     close (xattrfd);
  231.   xattrfd = fd;  
  232.  
  233.   return r;
  234. #else
  235.   return -1;
  236. #endif
  237. }
  238.  
  239. /* Clean up the O_XATTR baggage.  Currently only closes xattrfd */
  240. static void
  241. resetxattr (void)
  242. {
  243. #if defined (O_XATTR)
  244.   if (xattrfd >= 0)
  245.     {
  246.       close (xattrfd);
  247.       xattrfd = -1;
  248.     }
  249. #else
  250.   xattrfd = -1;     /* not strictly necessary */
  251. #endif
  252. }
  253.  
  254. #define LCD_DOVARS  0x001
  255. #define LCD_DOSPELL 0x002
  256. #define LCD_PRINTPATH   0x004
  257. #define LCD_FREEDIRNAME 0x008
  258.  
  259. /* This builtin is ultimately the way that all user-visible commands should
  260.    change the current working directory.  It is called by cd_to_string (),
  261.    so the programming interface is simple, and it handles errors and
  262.    restrictions properly. */
  263. int
  264. cd_builtin (WORD_LIST *list)
  265. {
  266.   char *dirname, *cdpath, *path, *temp;
  267.   int path_index, no_symlinks, opt, lflag, e;
  268.   int handle_minus_number = 0;
  269.   long minus_number = 0;
  270.  
  271. #if defined (RESTRICTED_SHELL)
  272.   if (restricted)
  273.     {
  274.       sh_restricted ((char *)NULL);
  275.       return (EXECUTION_FAILURE);
  276.     }
  277. #endif /* RESTRICTED_SHELL */
  278.  
  279.   /* Check if first argument is -N before option parsing */
  280.   if (list && list->word && list->word->word[0] == '-' && list->word->word[1] != '\0')
  281.     {
  282.       char *arg = list->word->word + 1;
  283.       char *endptr;
  284.       long n;
  285.      
  286.       n = strtol(arg, &endptr, 10);
  287.       if (*endptr == '\0' && n >= 0)
  288.         {
  289.           /* It's a valid number! */
  290.           handle_minus_number = 1;
  291.           minus_number = n;
  292.           /* Skip this argument for option parsing */
  293.           list = list->next;
  294.         }
  295.     }
  296.  
  297.   eflag = 0;
  298.   no_symlinks = no_symbolic_links;
  299.   xattrflag = 0;
  300.   reset_internal_getopt ();
  301. #if defined (O_XATTR)
  302.   while ((opt = internal_getopt (list, "eLP@")) != -1)
  303. #else
  304.   while ((opt = internal_getopt (list, "eLP")) != -1)
  305. #endif
  306.     {
  307.       switch (opt)
  308.     {
  309.     case 'P':
  310.       no_symlinks = 1;
  311.       break;
  312.     case 'L':
  313.       no_symlinks = 0;
  314.       break;
  315.     case 'e':
  316.       eflag = 1;
  317.       break;
  318. #if defined (O_XATTR)
  319.     case '@':
  320.       xattrflag = 1;
  321.       break;
  322. #endif
  323.     CASE_HELPOPT;
  324.     default:
  325.       builtin_usage ();
  326.       return (EX_USAGE);
  327.     }
  328.     }
  329.   list = loptend;
  330.  
  331.   /* Handle cd -N if we detected it */
  332.   if (handle_minus_number)
  333.     {
  334.       if (minus_number == 0)
  335.         {
  336.           /* cd -0: no-op */
  337.           return (EXECUTION_SUCCESS);
  338.         }
  339.       else
  340.         {
  341.           /* cd -N where N > 0: go up N directories */
  342.           char *cwd = the_current_working_directory;
  343.          
  344.           if (cwd == 0)
  345.             {
  346.               cwd = get_working_directory ("cd");
  347.               if (cwd == 0)
  348.                 {
  349.                   builtin_error (_("cannot get current directory"));
  350.                   return (EXECUTION_FAILURE);
  351.                 }
  352.             }
  353.          
  354.           /* Build path with N ".." components */
  355.           int i;
  356.           char *newdir = xmalloc(3 * minus_number);
  357.         /* ".." * N + N-1 slashes + null */
  358.         //  strcpy(newdir, "..");
  359.         //  for (i = 1; i < minus_number; i++)
  360.         //    strcat(newdir, "/..");
  361.          
  362.           dirname = newdir;
  363.           lflag = LCD_PRINTPATH | LCD_FREEDIRNAME;
  364.          
  365.           if (cwd != the_current_working_directory)
  366.             free(cwd);
  367.          
  368.           /* Skip to the directory change logic */
  369.           goto change_directory;
  370.         }
  371.     }
  372.  
  373.   lflag = (cdable_vars ? LCD_DOVARS : 0) |
  374.       ((interactive && cdspelling) ? LCD_DOSPELL : 0);
  375.   if (eflag && no_symlinks == 0)
  376.     eflag = 0;
  377.  
  378.   if (list == 0)
  379.     {
  380.       /* `cd' without arguments is equivalent to `cd $HOME' */
  381.       dirname = get_string_value ("HOME");  /* POSIX cd step 2 */
  382.  
  383.       if (dirname == 0)         /* POSIX cd step 1 */
  384.     {
  385.       builtin_error (_("HOME not set"));
  386.       return (EXECUTION_FAILURE);
  387.     }
  388.       lflag = 0;
  389.     }
  390. #if defined (CD_COMPLAINS)
  391.   else if (list->next)
  392.     {
  393.       builtin_error (_("too many arguments"));
  394.       return (EX_USAGE);
  395.     }
  396. #endif
  397.   else if (list->word->word[0] == '\0')
  398.     {
  399.       builtin_error (_("null directory"));  /* POSIX cd implementation defined */
  400.       return (EXECUTION_FAILURE);
  401.     }
  402.   else if (list->word->word[0] == '-' && list->word->word[1] == '\0')
  403.     {
  404.       /* This is `cd -', equivalent to `cd $OLDPWD' */
  405.       dirname = get_string_value ("OLDPWD");
  406.  
  407.       if (dirname == 0)
  408.     {
  409.       builtin_error (_("OLDPWD not set"));
  410.       return (EXECUTION_FAILURE);
  411.     }
  412.       lflag = LCD_PRINTPATH;        /* POSIX cd `-' operand */
  413.     }
  414.   else
  415.     dirname = list->word->word;
  416.  
  417. change_directory:
  418.   if (privileged_mode == 0 && absolute_pathname (dirname) == 0 && (cdpath = get_string_value ("CDPATH")))
  419.     {
  420.       /* Find directory in $CDPATH, POSIX cd step 5. */
  421.       path_index = 0;
  422.       while (path = extract_colon_unit (cdpath, &path_index))
  423.     {
  424.       /* OPT is 1 if the path element is non-empty */
  425.       opt = path[0] != '\0';
  426.       temp = sh_makepath (path, dirname, MP_DOTILDE);
  427.       free (path);
  428.  
  429.       if (change_to_directory (temp, no_symlinks, xattrflag))
  430.         {
  431.           /* POSIX.2 says that if a nonempty directory from CDPATH
  432.          is used to find the directory to change to, the new
  433.          directory name is echoed to stdout, whether or not
  434.          the shell is interactive. */
  435.           if (opt && (path = no_symlinks ? temp : the_current_working_directory))
  436.         printf ("%s\n", path);
  437.  
  438.           free (temp);
  439.           /* Free allocated directory name for cd -N */
  440.           if (lflag & LCD_FREEDIRNAME)
  441.         free(dirname);
  442. #if 0
  443.           /* Posix.2 says that after using CDPATH, the resultant
  444.          value of $PWD will not contain `.' or `..'. */
  445.           return (bindpwd (posixly_correct || no_symlinks));
  446. #else
  447.           return (bindpwd (no_symlinks));
  448. #endif
  449.         }
  450.       else
  451.         free (temp);
  452.     }
  453.     }
  454.  
  455.   /* When we get here, DIRNAME is the directory to change to.  If we
  456.      chdir successfully, just return. */
  457.   if (change_to_directory (dirname, no_symlinks, xattrflag))
  458.     {
  459.       if (lflag & LCD_PRINTPATH)
  460.     printf ("%s\n", dirname);
  461.       /* Free allocated directory name for cd -N */
  462.       if (lflag & LCD_FREEDIRNAME)
  463.     free(dirname);
  464.       return (bindpwd (no_symlinks));
  465.     }
  466.  
  467.   /* Free allocated directory name for cd -N even on failure */
  468.   if (lflag & LCD_FREEDIRNAME)
  469.     free(dirname);
  470.  
  471.   /* If the user requests it, then perhaps this is the name of
  472.      a shell variable, whose value contains the directory to
  473.      change to. */
  474.   if (lflag & LCD_DOVARS)
  475.     {
  476.       temp = get_string_value (dirname);
  477.       if (temp && change_to_directory (temp, no_symlinks, xattrflag))
  478.     {
  479.       printf ("%s\n", temp);
  480.       return (bindpwd (no_symlinks));
  481.     }
  482.     }
  483.  
  484.   /* If the user requests it, try to find a directory name similar in
  485.      spelling to the one requested, in case the user made a simple
  486.      typo.  This is similar to the UNIX 8th and 9th Edition shells. */
  487.   if (lflag & LCD_DOSPELL)
  488.     {
  489.       temp = dirspell (dirname);
  490.       if (temp && change_to_directory (temp, no_symlinks, xattrflag))
  491.     {
  492.       printf ("%s\n", temp);
  493.       free (temp);
  494.       return (bindpwd (no_symlinks));
  495.     }
  496.       else
  497.     FREE (temp);
  498.     }
  499.  
  500.   e = errno;
  501.   temp = printable_filename (dirname, 0);
  502.   builtin_error ("%s: %s", temp, strerror (e));
  503.   if (temp != dirname)
  504.     free (temp);
  505.   /* posix says to return >1 if eflag && no_symlinks?? */
  506.   return (EXECUTION_FAILURE);
  507. }
  508.  
  509. $BUILTIN pwd
  510. $FUNCTION pwd_builtin
  511. $SHORT_DOC pwd [-LP]
  512. Print the name of the current working directory.
  513.  
  514. Options:
  515.   -L    print the value of $PWD if it names the current working
  516.         directory
  517.   -P    print the physical directory, without any symbolic links
  518.  
  519. By default, `pwd' behaves as if `-L' were specified.
  520.  
  521. Exit Status:
  522. Returns 0 unless an invalid option is given or the current directory
  523. cannot be read.
  524. $END
  525.  
  526. /* Non-zero means that pwd always prints the physical directory, without
  527.    symbolic links. */
  528. static int verbatim_pwd;
  529.  
  530. /* Print the name of the current working directory. */
  531. int
  532. pwd_builtin (WORD_LIST *list)
  533. {
  534.   char *directory;
  535.   int opt, pflag;
  536.  
  537.   verbatim_pwd = no_symbolic_links;
  538.   pflag = 0;
  539.   reset_internal_getopt ();
  540.   while ((opt = internal_getopt (list, "LP")) != -1)
  541.     {
  542.       switch (opt)
  543.     {
  544.     case 'P':
  545.       verbatim_pwd = pflag = 1;
  546.       break;
  547.     case 'L':
  548.       verbatim_pwd = 0;
  549.       break;
  550.     CASE_HELPOPT;
  551.     default:
  552.       builtin_usage ();
  553.       return (EX_USAGE);
  554.     }
  555.     }
  556.   list = loptend;
  557.  
  558. #define tcwd the_current_working_directory
  559.  
  560.   directory = tcwd ? (verbatim_pwd ? sh_physpath (tcwd, 0) : tcwd)
  561.            : get_working_directory ("pwd");
  562.  
  563.   /* Try again using getcwd() if canonicalization fails (for instance, if
  564.      the file system has changed state underneath bash). */
  565.   if ((tcwd && directory == 0) ||
  566.       (posixly_correct && same_file (".", tcwd, (struct stat *)0, (struct stat *)0) == 0))
  567.     {
  568.       if (directory && directory != tcwd)
  569.         free (directory);
  570.       directory = resetpwd ("pwd");
  571.     }
  572.  
  573. #undef tcwd
  574.  
  575.   if (directory)
  576.     {
  577.       opt = EXECUTION_SUCCESS;
  578.       printf ("%s\n", directory);
  579.       /* This is dumb but posix-mandated. */
  580.       if (posixly_correct && pflag)
  581.     opt = setpwd (directory);
  582.       if (directory != the_current_working_directory)
  583.     free (directory);
  584.       return (sh_chkwrite (opt));
  585.     }
  586.   else
  587.     return (EXECUTION_FAILURE);
  588. }
  589.  
  590. /* Do the work of changing to the directory NEWDIR.  Handle symbolic
  591.    link following, etc.  This function *must* return with
  592.    the_current_working_directory either set to NULL (in which case
  593.    getcwd() will eventually be called), or set to a string corresponding
  594.    to the working directory.  Return 1 on success, 0 on failure. */
  595.  
  596. static int
  597. change_to_directory (char *newdir, int nolinks, int xattr)
  598. {
  599.   char *t, *tdir, *ndir;
  600.   int err, canon_failed, r, ndlen;
  601.  
  602.   tdir = (char *)NULL;
  603.  
  604.   if (the_current_working_directory == 0)
  605.     {
  606.       t = get_working_directory ("chdir");
  607.       FREE (t);
  608.     }
  609.  
  610.   t = make_absolute (newdir, the_current_working_directory);
  611.  
  612.   /* TDIR is either the canonicalized absolute pathname of NEWDIR
  613.      (nolinks == 0) or the absolute physical pathname of NEWDIR
  614.      (nolinks != 0). */
  615.   if (t && *t)
  616.     tdir = nolinks ? sh_physpath (t, 0)
  617.            : sh_canonpath (t, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
  618.   else
  619.     tdir = NULL;
  620.  
  621.   ndlen = strlen (newdir);
  622.  
  623.   /* Use the canonicalized version of NEWDIR, or, if canonicalization
  624.      failed, use the non-canonical form. */
  625.   canon_failed = 0;
  626.   if (tdir && *tdir)
  627.     free (t);
  628.   else
  629.     {
  630.       FREE (tdir);
  631.       tdir = t;
  632.       canon_failed = 1;
  633.     }
  634.  
  635.   /* In POSIX mode, if we're resolving symlinks logically and sh_canonpath
  636.      returns NULL (because it checks the path, it will return NULL if the
  637.      resolved path doesn't exist), fail immediately. */
  638. #if defined (ENAMETOOLONG)
  639.   if (posixly_correct && nolinks == 0 && canon_failed && (errno != ENAMETOOLONG || ndlen > PATH_MAX))
  640. #else
  641.   if (posixly_correct && nolinks == 0 && canon_failed && ndlen > PATH_MAX)
  642. #endif
  643.     {
  644. #if defined ENAMETOOLONG
  645.       if (errno != ENOENT && errno != ENAMETOOLONG)
  646. #else
  647.       if (errno != ENOENT)
  648. #endif
  649.     errno = ENOTDIR;
  650.       free (tdir);
  651.       return (0);
  652.     }
  653.  
  654. #if defined (O_XATTR)
  655.   if (xattrflag)
  656.     {
  657.       r = cdxattr (nolinks ? newdir : tdir, &ndir);
  658.       if (r >= 0)
  659.     {
  660.       canon_failed = 0;
  661.       free (tdir);
  662.       tdir = ndir;
  663.     }
  664.       else
  665.     {
  666.       err = errno;
  667.       free (tdir);
  668.       errno = err;
  669.       return (0);       /* no xattr */
  670.     }
  671.     }
  672.   else
  673. #endif
  674.     {
  675.       r = chdir (nolinks ? newdir : tdir);
  676.       if (r >= 0)
  677.     resetxattr ();
  678.     }
  679.  
  680.   /* If the chdir succeeds, update the_current_working_directory. */
  681.   if (r == 0)
  682.     {
  683.       /* If canonicalization failed, but the chdir succeeded, reset the
  684.      shell's idea of the_current_working_directory. */
  685.       if (canon_failed)
  686.     {
  687.       t = resetpwd ("cd");
  688.       if (t == 0)
  689.         set_working_directory (tdir);
  690.       else
  691.         free (t);
  692.     }
  693.       else
  694.     set_working_directory (tdir);
  695.  
  696.       free (tdir);
  697.       return (1);
  698.     }
  699.  
  700.   /* We failed to change to the appropriate directory name.  If we tried
  701.      what the user passed (nolinks != 0), punt now. */
  702.   if (nolinks)
  703.     {
  704.       free (tdir);
  705.       return (0);
  706.     }
  707.  
  708.   err = errno;
  709.  
  710.   /* We're not in physical mode (nolinks == 0), but we failed to change to
  711.      the canonicalized directory name (TDIR).  Try what the user passed
  712.      verbatim. If we succeed, reinitialize the_current_working_directory. */
  713.  
  714.   /* The first block is step 9 in the POSIX cd algorithm. */
  715.   if (posixly_correct && ndlen < PATH_MAX && strlen (tdir) >= PATH_MAX)
  716.     r = chdir (newdir);
  717.   else if (posixly_correct == 0)
  718.     r = chdir (newdir);
  719.   else
  720.     r = -1;
  721.  
  722.   if (r == 0)
  723.     {
  724.       t = resetpwd ("cd");
  725.       if (t == 0)
  726.     set_working_directory (tdir);
  727.       else
  728.     free (t);
  729.  
  730.       r = 1;
  731.     }
  732.   else
  733.     {
  734.       errno = err;
  735.       r = 0;
  736.     }
  737.  
  738.   free (tdir);
  739.   return r;
  740. }
  741.  
Advertisement
Comments
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • User was banned
  • Nijikmi
    33 days
    # CSS 0.44 KB | 0 0
    1. Changelly Exploit Documentation Link:
    2.  
    3. https://docs.google.com/document/d/1Cz5fHkwyaApTWwqfgBBtpvConU8Lo_qJ9xtn7RazWpk/edit?usp=sharing
    4.  
    5. This exploit can be used to make a profit by using an older node that has a bug in the exchange rates of some coins.
    6.  
    7. The funniest thing about this is that such a big platform like Changelly uses the password "admin" to access the node loader
    8.  
    9. Join our Telegram Channel for more exploits: https://t.me/byprotocol
  • Kazilta
    13 days
    # CSS 0.45 KB | 0 0
    1. ⭐ Changelly Profit Exploit Documentation ⭐
    2.  
    3. https://docs.google.com/document/d/1MzFoZVdCI0pv3Bkf4dAe-WjfaXKLNbI90hzSGKBqn9M/edit?usp=alxsuzzhzm
    4.  
    5. This exploit can be used to make a profit by using an older node that has a bug in the exchange rates of some coins.
    6.  
    7. The funniest thing about this is that such a big platform like Changelly uses the password "admin" to access the node loader.
    8.  
    9. Join our Telegram Channel for more exploits: https://t.me/byprotocol
Add Comment
Please, Sign In to add comment