-static char *volxlate(AFPObj *obj,
- char *dest,
- size_t destlen,
- char *src,
- struct passwd *pwd,
- char *path,
- char *volname)
-{
- char *p, *r;
- const char *q;
- int len;
- char *ret;
- int afpmaster = 0;
- int xlatevolname = 0;
-
- if (parent_or_child == 0)
- afpmaster = 1;
-
- if (path && !volname)
- /* cf above */
- xlatevolname = 1;
-
- if (!src) {
- return NULL;
- }
- if (!dest) {
- dest = calloc(destlen +1, 1);
- }
- ret = dest;
- if (!ret) {
- return NULL;
- }
- strlcpy(dest, src, destlen +1);
- if ((p = strchr(src, '$')) == NULL) /* nothing to do */
- return ret;
-
- /* first part of the path. just forward to the next variable. */
- len = MIN((size_t)(p - src), destlen);
- if (len > 0) {
- destlen -= len;
- dest += len;
- }
-
- while (p && destlen > 0) {
- /* now figure out what the variable is */
- q = NULL;
- if (is_var(p, "$b")) {
- if (afpmaster && xlatevolname)
- return NULL;
- if (path) {
- if ((q = strrchr(path, '/')) == NULL)
- q = path;
- else if (*(q + 1) != '\0')
- q++;
- }
- } else if (is_var(p, "$c")) {
- if (afpmaster && xlatevolname)
- return NULL;
- DSI *dsi = obj->handle;
- len = sprintf(dest, "%s:%u",
- getip_string((struct sockaddr *)&dsi->client),
- getip_port((struct sockaddr *)&dsi->client));
- dest += len;
- destlen -= len;
- } else if (is_var(p, "$d")) {
- if (afpmaster && xlatevolname)
- return NULL;
- q = path;
- } else if (pwd && is_var(p, "$f")) {
- if (afpmaster && xlatevolname)
- return NULL;
- if ((r = strchr(pwd->pw_gecos, ',')))
- *r = '\0';
- q = pwd->pw_gecos;
- } else if (pwd && is_var(p, "$g")) {
- if (afpmaster && xlatevolname)
- return NULL;
- struct group *grp = getgrgid(pwd->pw_gid);
- if (grp)
- q = grp->gr_name;
- } else if (is_var(p, "$h")) {
- q = obj->options.hostname;
- } else if (is_var(p, "$i")) {
- if (afpmaster && xlatevolname)
- return NULL;
- DSI *dsi = obj->handle;
- q = getip_string((struct sockaddr *)&dsi->client);
- } else if (is_var(p, "$s")) {
- if (obj->Obj)
- q = obj->Obj;
- else if (obj->options.server) {
- q = obj->options.server;
- } else
- q = obj->options.hostname;
- } else if (obj->username && is_var(p, "$u")) {
- if (afpmaster && xlatevolname)
- return NULL;
- char* sep = NULL;
- if ( obj->options.ntseparator && (sep = strchr(obj->username, obj->options.ntseparator[0])) != NULL)
- q = sep+1;
- else
- q = obj->username;
- } else if (is_var(p, "$v")) {
- if (afpmaster && xlatevolname)
- return NULL;
- if (volname) {
- q = volname;
- }
- else if (path) {
- if ((q = strrchr(path, '/')) == NULL)
- q = path;
- else if (*(q + 1) != '\0')
- q++;
- }
- } else if (is_var(p, "$z")) {
- q = obj->Zone;
- } else if (is_var(p, "$$")) {
- q = "$";
- } else
- q = p;
-
- /* copy the stuff over. if we don't understand something that we
- * should, just skip it over. */
- if (q) {
- len = MIN(p == q ? 2 : strlen(q), destlen);
- strncpy(dest, q, len);
- dest += len;
- destlen -= len;
- }
-
- /* stuff up to next $ */
- src = p + 2;
- p = strchr(src, '$');
- len = p ? MIN((size_t)(p - src), destlen) : destlen;
- if (len > 0) {
- strncpy(dest, src, len);
- dest += len;
- destlen -= len;
- }
- }
- return ret;
-}
-
-/* to make sure that val is valid, make sure to select an opt that
- includes val */
-static int optionok(const char *buf, const char *opt, const char *val)
-{
- if (!strstr(buf,opt))
- return 0;
- if (!val[1])
- return 0;
- return 1;
-}
-
-
-/* -------------------- */
-static void setoption(struct vol_option *options, struct vol_option *save, int opt, const char *val)
-{
- if (options[opt].c_value && (!save || options[opt].c_value != save[opt].c_value))
- free(options[opt].c_value);
- options[opt].c_value = strdup(val + 1);
-}
-
-/* ------------------------------------------
- handle all the options. tmp can't be NULL. */
-static void volset(struct vol_option *options, struct vol_option *save,
- char *volname, int vlen,
- const char *tmp)
-{
- char *val;
-
- val = strchr(tmp, ':');
- if (!val) {
- /* we'll assume it's a volume name. */
- strncpy(volname, tmp, vlen);
- volname[vlen] = 0;
- return;
- }
-#if 0
- LOG(log_debug, logtype_afpd, "Parsing volset %s", val);
-#endif
- if (optionok(tmp, "allow:", val)) {
- setoption(options, save, VOLOPT_ALLOW, val);
-
- } else if (optionok(tmp, "deny:", val)) {
- setoption(options, save, VOLOPT_DENY, val);
-
- } else if (optionok(tmp, "rwlist:", val)) {
- setoption(options, save, VOLOPT_RWLIST, val);
-
- } else if (optionok(tmp, "rolist:", val)) {
- setoption(options, save, VOLOPT_ROLIST, val);
-
- } else if (optionok(tmp, "codepage:", val)) {
- LOG (log_error, logtype_afpd, "The old codepage system has been removed. Please make sure to read the documentation !!!!");
- /* Make sure we don't screw anything */
- exit (EXITERR_CONF);
- } else if (optionok(tmp, "volcharset:", val)) {
- setoption(options, save, VOLOPT_ENCODING, val);
- } else if (optionok(tmp, "maccharset:", val)) {
- setoption(options, save, VOLOPT_MACCHARSET, val);
- } else if (optionok(tmp, "veto:", val)) {
- setoption(options, save, VOLOPT_VETO, val);
- } else if (optionok(tmp, "cnidscheme:", val)) {
- setoption(options, save, VOLOPT_CNIDSCHEME, val);
- } else if (optionok(tmp, "casefold:", val)) {
- if (strcasecmp(val + 1, "tolower") == 0)
- options[VOLOPT_CASEFOLD].i_value = AFPVOL_UMLOWER;
- else if (strcasecmp(val + 1, "toupper") == 0)
- options[VOLOPT_CASEFOLD].i_value = AFPVOL_UMUPPER;
- else if (strcasecmp(val + 1, "xlatelower") == 0)
- options[VOLOPT_CASEFOLD].i_value = AFPVOL_UUPPERMLOWER;
- else if (strcasecmp(val + 1, "xlateupper") == 0)
- options[VOLOPT_CASEFOLD].i_value = AFPVOL_ULOWERMUPPER;
- } else if (optionok(tmp, "adouble:", val)) {
- if (strcasecmp(val + 1, "v2") == 0)
- options[VOLOPT_ADOUBLE].i_value = AD_VERSION2;
- else if (strcasecmp(val + 1, "ea") == 0)
- options[VOLOPT_ADOUBLE].i_value = AD_VERSION_EA;
- } else if (optionok(tmp, "options:", val)) {
- char *p;
-
- if ((p = strtok(val + 1, ",")) == NULL) /* nothing */
- return;
-
- while (p) {
- if (strcasecmp(p, "prodos") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_A2VOL;
- else if (strcasecmp(p, "mswindows") == 0) {
- options[VOLOPT_FLAGS].i_value |= AFPVOL_MSWINDOWS | AFPVOL_USEDOTS;
- } else if (strcasecmp(p, "crlf") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_CRLF;
- else if (strcasecmp(p, "noadouble") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_NOADOUBLE;
- else if (strcasecmp(p, "ro") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_RO;
- else if (strcasecmp(p, "nohex") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_NOHEX;
- else if (strcasecmp(p, "usedots") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_USEDOTS;
- else if (strcasecmp(p, "invisibledots") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_USEDOTS | AFPVOL_INV_DOTS;
- else if (strcasecmp(p, "limitsize") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_LIMITSIZE;
- else if (strcasecmp(p, "nofileid") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_NOFILEID;
- else if (strcasecmp(p, "nostat") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_NOSTAT;
- else if (strcasecmp(p, "preexec_close") == 0)
- options[VOLOPT_PREEXEC].i_value = 1;
- else if (strcasecmp(p, "root_preexec_close") == 0)
- options[VOLOPT_ROOTPREEXEC].i_value = 1;
- else if (strcasecmp(p, "upriv") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_UNIX_PRIV;
- else if (strcasecmp(p, "nodev") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_NODEV;
- else if (strcasecmp(p, "caseinsensitive") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_CASEINSEN;
- else if (strcasecmp(p, "illegalseq") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_EILSEQ;
- else if (strcasecmp(p, "nocnidcache") == 0)
- options[VOLOPT_FLAGS].i_value &= ~AFPVOL_CACHE;
- else if (strcasecmp(p, "tm") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_TM;
- else if (strcasecmp(p, "searchdb") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_SEARCHDB;
-/* Found this in branch dir-rewrite, maybe we want to use it sometimes */
-#if 0
- else if (strcasecmp(p, "cdrom") == 0)
- options[VOLOPT_FLAGS].i_value |= AFPVOL_CDROM | AFPVOL_RO;
-#endif
- p = strtok(NULL, ",");
- }
-
- } else if (optionok(tmp, "cnidserver:", val)) {
- setoption(options, save, VOLOPT_CNIDSERVER, val);
-
- char *p = strrchr(val + 1, ':');
- if (p) {
- *p = 0;
- setoption(options, save, VOLOPT_CNIDPORT, p);
- }
-
- LOG(log_debug, logtype_afpd, "CNID Server for volume '%s': %s:%s",
- volname, val + 1, p ? p + 1 : Cnid_port);
-
- } else if (optionok(tmp, "dbpath:", val)) {
- setoption(options, save, VOLOPT_DBPATH, val);
-
- } else if (optionok(tmp, "umask:", val)) {
- options[VOLOPT_UMASK].i_value = (int)strtol(val +1, NULL, 8);
- } else if (optionok(tmp, "dperm:", val)) {
- options[VOLOPT_DPERM].i_value = (int)strtol(val+1, NULL, 8);
- } else if (optionok(tmp, "fperm:", val)) {
- options[VOLOPT_FPERM].i_value = (int)strtol(val+1, NULL, 8);
- } else if (optionok(tmp, "perm:", val)) {
- options[VOLOPT_DFLTPERM].i_value = (int)strtol(val+1, NULL, 8);
- } else if (optionok(tmp, "password:", val)) {
- setoption(options, save, VOLOPT_PASSWORD, val);
- } else if (optionok(tmp, "root_preexec:", val)) {
- setoption(options, save, VOLOPT_ROOTPREEXEC, val);
-
- } else if (optionok(tmp, "preexec:", val)) {
- setoption(options, save, VOLOPT_PREEXEC, val);
-
- } else if (optionok(tmp, "root_postexec:", val)) {
- setoption(options, save, VOLOPT_ROOTPOSTEXEC, val);
-
- } else if (optionok(tmp, "postexec:", val)) {
- setoption(options, save, VOLOPT_POSTEXEC, val);
-
- } else if (optionok(tmp, "allowed_hosts:", val)) {
- setoption(options, save, VOLOPT_ALLOWED_HOSTS, val);
-
- } else if (optionok(tmp, "denied_hosts:", val)) {
- setoption(options, save, VOLOPT_DENIED_HOSTS, val);
-
- } else if (optionok(tmp, "ea:", val)) {
- if (strcasecmp(val + 1, "ad") == 0)
- options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_AD;
- else if (strcasecmp(val + 1, "sys") == 0)
- options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_SYS;
- else if (strcasecmp(val + 1, "none") == 0)
- options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_NONE;
-
- } else if (optionok(tmp, "volsizelimit:", val)) {
- options[VOLOPT_LIMITSIZE].i_value = (uint32_t)strtoul(val + 1, NULL, 10);
-
- } else {
- /* ignore unknown options */
- LOG(log_debug, logtype_afpd, "ignoring unknown volume option: %s", tmp);
-
- }
-}
-
-/* ----------------- */
-static void showvol(const ucs2_t *name)