| 138 | }; |
| 139 | |
| 140 | static char * |
| 141 | substvar(const char * var, const struct passwd * pwd, int hlen, int pch, int nlen) |
| 142 | { |
| 143 | char *np = NULL; |
| 144 | |
| 145 | if (var != NULL) { |
| 146 | int tildes = 0; |
| 147 | int dollas = 0; |
| 148 | char *p; |
| 149 | const char *q; |
| 150 | |
| 151 | if (pwd != NULL) { |
| 152 | for (q = var; *q != '\0'; ++q) { |
| 153 | tildes += (*q == '~'); |
| 154 | dollas += (*q == '$'); |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | np = malloc(strlen(var) + (dollas * nlen) |
| 159 | - dollas + (tildes * (pch+hlen)) |
| 160 | - tildes + 1); |
| 161 | |
| 162 | if (np != NULL) { |
| 163 | p = strcpy(np, var); |
| 164 | |
| 165 | if (pwd != NULL) { |
| 166 | /* |
| 167 | * This loop does user username and homedir substitutions |
| 168 | * for unescaped $ (username) and ~ (homedir) |
| 169 | */ |
| 170 | while (*(p += strcspn(p, "~$")) != '\0') { |
| 171 | int l = strlen(p); |
| 172 | |
| 173 | if (p > np && *(p-1) == '\\') /* Escaped: */ |
| 174 | memmove(p - 1, p, l + 1); /* Slide-out the backslash */ |
| 175 | else if (*p == '~') { |
| 176 | int v = pch && *(p+1) != '/'; /* Avoid double // */ |
| 177 | memmove(p + hlen + v, p + 1, l); /* Subst homedir */ |
| 178 | memmove(p, pwd->pw_dir, hlen); |
| 179 | if (v) |
| 180 | p[hlen] = '/'; |
| 181 | p += hlen + v; |
| 182 | } |
| 183 | else /* if (*p == '$') */ { |
| 184 | memmove(p + nlen, p + 1, l); /* Subst username */ |
| 185 | memmove(p, pwd->pw_name, nlen); |
| 186 | p += nlen; |
| 187 | } |
| 188 | } |
| 189 | } |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | return (np); |
| 194 | } |
| 195 | |
| 196 | |
| 197 | void |
no test coverage detected