"Fossies" - the Fresh Open Source Software Archive

Member "links-1.04/smb.c" (12 Oct 2018, 19844 Bytes) of package /linux/www/links-1.04.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "smb.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.03_vs_1.04.

    1 #include "links.h"
    2 
    3 #ifndef DISABLE_SMB
    4 
    5 #define SMBCLIENT   0
    6 #define SMBC        1
    7 #define N_CLIENTS   2
    8 
    9 static int smb_client = 0;
   10 
   11 #define CLIENT_NOT_FOUND_STRING "client not found"
   12 
   13 struct smb_connection_info {
   14     int client;
   15     int list;
   16     int cl;
   17     int ntext;
   18     unsigned char text[1];
   19 };
   20 
   21 static void smb_got_data(struct connection *);
   22 static void smb_got_text(struct connection *);
   23 static void end_smb_connection(struct connection *);
   24 
   25 void smb_func(struct connection *c)
   26 {
   27     int i;
   28     int po[2];
   29     int pe[2];
   30     unsigned char *host, *user, *pass, *port, *data1, *data, *share, *dir;
   31     int datal;
   32     unsigned char *p;
   33     pid_t r;
   34     int rs;
   35     struct smb_connection_info *si;
   36     si = mem_alloc(sizeof(struct smb_connection_info) + 2);
   37     memset(si, 0, sizeof(struct smb_connection_info));
   38     c->info = si;
   39     si->client = smb_client;
   40     host = get_host_name(c->url);
   41     if (!host) {
   42         setcstate(c, S_INTERNAL);
   43         abort_connection(c);
   44         return;
   45     }
   46     if (!(user = get_user_name(c->url))) user = stracpy(cast_uchar "");
   47     if (!(pass = get_pass(c->url))) pass = stracpy(cast_uchar "");
   48     if (!(port = get_port_str(c->url))) port = stracpy(cast_uchar "");
   49     if (!(data1 = get_url_data(c->url))) data1 = cast_uchar "";
   50     data = init_str(), datal = 0;
   51     add_conv_str(&data, &datal, data1, (int)strlen(cast_const_char data1), -2);
   52 
   53     for (i = 0; data[i]; i++) if (data[i] < 32 || data[i] == ';' || (data[i] == '"' && smb_client == SMBCLIENT)) {
   54 /* ';' shouldn't cause security problems but samba doesn't like it */
   55 /* '"' is allowed for smbc */
   56         mem_free(host);
   57         mem_free(port);
   58         mem_free(user);
   59         mem_free(pass);
   60         mem_free(data);
   61         setcstate(c, S_BAD_URL);
   62         abort_connection(c);
   63         return;
   64     }
   65 
   66     if ((p = cast_uchar strchr(cast_const_char data, '/'))) share = memacpy(data, p - data), dir = p + 1;
   67     else if (*data) {
   68         if (!c->cache) {
   69             if (get_cache_entry(c->url, &c->cache)) {
   70                 mem_free(host);
   71                 mem_free(port);
   72                 mem_free(user);
   73                 mem_free(pass);
   74                 mem_free(data);
   75                 setcstate(c, S_OUT_OF_MEM);
   76                 abort_connection(c);
   77                 return;
   78             }
   79             c->cache->refcount--;
   80         }
   81         if (c->cache->redirect) mem_free(c->cache->redirect);
   82         c->cache->redirect = stracpy(c->url);
   83         c->cache->redirect_get = 1;
   84         add_to_strn(&c->cache->redirect, cast_uchar "/");
   85         c->cache->incomplete = 0;
   86         mem_free(host);
   87         mem_free(port);
   88         mem_free(user);
   89         mem_free(pass);
   90         mem_free(data);
   91         setcstate(c, S__OK);
   92         abort_connection(c);
   93         return;
   94     } else share = stracpy(cast_uchar ""), dir = cast_uchar "";
   95     if (!*share) si->list = 1;
   96     else if (!*dir || dir[strlen(cast_const_char dir) - 1] == '/' || dir[strlen(cast_const_char dir) - 1] == '\\') si->list = 2;
   97     if (c_pipe(po)) {
   98         int err = errno;
   99         mem_free(host);
  100         mem_free(port);
  101         mem_free(user);
  102         mem_free(pass);
  103         mem_free(share);
  104         mem_free(data);
  105         setcstate(c, get_error_from_errno(err));
  106         abort_connection(c);
  107         return;
  108     }
  109     if (c_pipe(pe)) {
  110         int err = errno;
  111         mem_free(host);
  112         mem_free(port);
  113         mem_free(user);
  114         mem_free(pass);
  115         mem_free(share);
  116         mem_free(data);
  117         EINTRLOOP(rs, close(po[0]));
  118         EINTRLOOP(rs, close(po[1]));
  119         setcstate(c, get_error_from_errno(err));
  120         abort_connection(c);
  121         return;
  122     }
  123     c->from = 0;
  124     EINTRLOOP(r, fork());
  125     if (r == -1) {
  126         int err = errno;
  127         mem_free(host);
  128         mem_free(port);
  129         mem_free(user);
  130         mem_free(pass);
  131         mem_free(share);
  132         mem_free(data);
  133         EINTRLOOP(rs, close(po[0]));
  134         EINTRLOOP(rs, close(po[1]));
  135         EINTRLOOP(rs, close(pe[0]));
  136         EINTRLOOP(rs, close(pe[1]));
  137         setcstate(c, get_error_from_errno(err));
  138         retry_connection(c);
  139         return;
  140     }
  141     if (!r) {
  142         int n;
  143         unsigned char *v[32];
  144         unsigned char *uphp;
  145         close_fork_tty();
  146         EINTRLOOP(rs, close(1));
  147         if (si->list)
  148             EINTRLOOP(rs, dup2(pe[1], 1));
  149         else
  150             EINTRLOOP(rs, dup2(po[1], 1));
  151         EINTRLOOP(rs, close(2));
  152         EINTRLOOP(rs, dup2(pe[1], 2));
  153         EINTRLOOP(rs, close(0));
  154         EINTRLOOP(rs, open("/dev/null", O_RDONLY));
  155         EINTRLOOP(rs, close(po[0]));
  156         EINTRLOOP(rs, close(pe[0]));
  157         EINTRLOOP(rs, close(po[1]));
  158         EINTRLOOP(rs, close(pe[1]));
  159         n = 0;
  160         switch (si->client) {
  161         case SMBCLIENT:
  162             v[n++] = cast_uchar "smbclient";
  163             if (!*share) {
  164                 v[n++] = cast_uchar "-L";
  165                 v[n++] = host;
  166             } else {
  167                 unsigned char *s = stracpy(cast_uchar "//");
  168                 add_to_strn(&s, host);
  169                 add_to_strn(&s, cast_uchar "/");
  170                 add_to_strn(&s, share);
  171                 v[n++] = s;
  172                 if (*pass && !*user) {
  173                     v[n++] = pass;
  174                 }
  175             }
  176             v[n++] = cast_uchar "-N";
  177             v[n++] = cast_uchar "-E";
  178             if (*port) {
  179                 v[n++] = cast_uchar "-p";
  180                 v[n++] = port;
  181             }
  182             if (*user) {
  183                 v[n++] = cast_uchar "-U";
  184                 if (!*pass) {
  185                     v[n++] = user;
  186                 } else {
  187                     unsigned char *s = stracpy(user);
  188                     add_to_strn(&s, cast_uchar "%");
  189                     add_to_strn(&s, pass);
  190                     v[n++] = s;
  191                 }
  192             }
  193             if (*share) {
  194                 if (!*dir || dir[strlen(cast_const_char dir) - 1] == '/' || dir[strlen(cast_const_char dir) - 1] == '\\') {
  195                     if (*dir) {
  196                         v[n++] = cast_uchar "-D";
  197                         v[n++] = dir;
  198                     }
  199                     v[n++] = cast_uchar "-c";
  200                     v[n++] = cast_uchar "ls";
  201                 } else {
  202                     unsigned char *ss;
  203                     unsigned char *s = stracpy(cast_uchar "get \"");
  204                     add_to_strn(&s, dir);
  205                     add_to_strn(&s, cast_uchar "\" -");
  206                     while ((ss = cast_uchar strchr(cast_const_char s, '/'))) *ss = '\\';
  207                     v[n++] = cast_uchar "-c";
  208                     v[n++] = s;
  209                 }
  210             }
  211             break;
  212         case SMBC:
  213             v[n++] = cast_uchar "smbc";
  214             uphp = stracpy(cast_uchar "");
  215             if (*user) {
  216                 add_to_strn(&uphp, user);
  217                 if (*pass) {
  218                     add_to_strn(&uphp, cast_uchar ":");
  219                     add_to_strn(&uphp, pass);
  220                 }
  221                 add_to_strn(&uphp, cast_uchar "@");
  222             }
  223             add_to_strn(&uphp, host);
  224             if (*port) {
  225                 add_to_strn(&uphp, cast_uchar ":");
  226                 add_to_strn(&uphp, port);
  227             }
  228             if (!*share) {
  229                 v[n++] = cast_uchar "-L";
  230                 v[n++] = uphp;
  231             } else {
  232                 add_to_strn(&uphp, cast_uchar "/");
  233                 add_to_strn(&uphp, share);
  234                 if (!*dir || dir[strlen(cast_const_char dir) - 1] == '/' || dir[strlen(cast_const_char dir) - 1] == '\\') {
  235                     add_to_strn(&uphp, cast_uchar "/");
  236                     add_to_strn(&uphp, dir);
  237                     v[n++] = uphp;
  238                     v[n++] = cast_uchar "-c";
  239                     v[n++] = cast_uchar "ls";
  240                 } else {
  241                     unsigned char *d = init_str();
  242                     int dl = 0;
  243                     unsigned char *dp = dir;
  244                     v[n++] = uphp;
  245                     v[n++] = cast_uchar "-c";
  246                     add_to_str(&d, &dl, cast_uchar "pipe cat ");
  247                     while (*dp) {
  248                         if (*dp <= ' ' || *dp == '\\' || *dp == '"' || *dp == '\'' || *dp == '*' || *dp == '?') add_chr_to_str(&d, &dl, '\\');
  249                         add_chr_to_str(&d, &dl, *dp);
  250                         dp++;
  251                     }
  252                     v[n++] = d;
  253                 }
  254             }
  255             break;
  256         default:
  257             internal("unsupported smb client");
  258         }
  259         v[n++] = NULL;
  260         EINTRLOOP(rs, execvp(cast_const_char v[0], (void *)v));
  261         hard_write(2, cast_uchar CLIENT_NOT_FOUND_STRING, (int)strlen(CLIENT_NOT_FOUND_STRING));
  262         _exit(1);
  263     }
  264     c->pid = r;
  265     mem_free(host);
  266     mem_free(port);
  267     mem_free(user);
  268     mem_free(pass);
  269     mem_free(share);
  270     mem_free(data);
  271     c->sock1 = po[0];
  272     c->sock2 = pe[0];
  273     EINTRLOOP(rs, close(po[1]));
  274     EINTRLOOP(rs, close(pe[1]));
  275     set_handlers(po[0], (void (*)(void *))smb_got_data, NULL, NULL, c);
  276     set_handlers(pe[0], (void (*)(void *))smb_got_text, NULL, NULL, c);
  277     setcstate(c, S_CONN);
  278 }
  279 
  280 static int smbc_get_num(unsigned char *text, int *ptr, off_t *res)
  281 {
  282     off_t num;
  283     int dec, dec_order, unit;
  284     int was_digit;
  285     int i = *ptr;
  286     const off_t max_off_t = (((off_t)1 << ((sizeof(off_t) * 8 - 2))) - 1) * 2 + 1;
  287 
  288     while (text[i] == ' ' || text[i] == '\t') i++;
  289     was_digit = 0;
  290     num = 0;
  291     while (text[i] >= '0' && text[i] <= '9') {
  292         if (num >= max_off_t / 10) return -1;
  293         num = num * 10 + text[i] - '0';
  294         i++;
  295         was_digit = 1;
  296     }
  297     dec = 0; dec_order = 1;
  298     if (text[i] == '.') {
  299         i++;
  300         while (text[i] >= '0' && text[i] <= '9') {
  301             if (dec_order < 1000000) {
  302                 dec = dec * 10 + text[i] - '0';
  303                 dec_order *= 10;
  304             }
  305             i++;
  306             was_digit = 1;
  307         }
  308     }
  309     if (!was_digit) return -1;
  310     if (upcase(text[i]) == 'B') unit = 1;
  311     else if (upcase(text[i]) == 'K') unit = 1 << 10;
  312     else if (upcase(text[i]) == 'M') unit = 1 << 20;
  313     else if (upcase(text[i]) == 'G') unit = 1 << 30;
  314     else return -1;
  315     i++;
  316     *ptr = i;
  317     if (num >= max_off_t / unit) return -1;
  318     *res = num * unit + (off_t)((double)dec * ((double)unit / (double)dec_order));
  319     return 0;
  320 }
  321 
  322 static void smb_read_text(struct connection *c, int sock)
  323 {
  324     int r;
  325     struct smb_connection_info *si = c->info;
  326     if ((unsigned)sizeof(struct smb_connection_info) + si->ntext + page_size + 2 > MAXINT) overalloc();
  327     si = mem_realloc(si, sizeof(struct smb_connection_info) + si->ntext + page_size + 2);
  328     c->info = si;
  329     EINTRLOOP(r, (int)read(sock, si->text + si->ntext, page_size));
  330     if (r == -1) {
  331         setcstate(c, get_error_from_errno(errno));
  332         retry_connection(c);
  333         return;
  334     }
  335     if (r == 0) {
  336         if (!si->cl) {
  337             si->cl = 1;
  338             set_handlers(sock, NULL, NULL, NULL, NULL);
  339             return;
  340         }
  341         end_smb_connection(c);
  342         return;
  343     }
  344     si->ntext += r;
  345     if (!c->from) setcstate(c, S_GETH);
  346     if (c->from && si->client == SMBC) {
  347         int lasti = 0;
  348         int i = 0;
  349         si->text[si->ntext] = 0;
  350         for (i = 0; si->ntext - i > 7; i++) {
  351             nexti:
  352             if ((si->text[i] == '\n' || si->text[i] == '\r') && (si->text[i + 1] == ' ' || (si->text[i + 1] >= '0' && si->text[i + 1] <= '9')) && ((si->text[i + 2] == ' ' && si->text[i + 1] == ' ') || (si->text[i + 2] >= '0' && si->text[i + 2] <= '9')) && (si->text[i + 3] >= '0' && si->text[i + 3] <= '9') && si->text[i + 4] == '%' && si->text[i + 5] == ' ' && si->text[i + 6] == '[') {
  353                 off_t position, total = 0; /* against warning */
  354                 i += 7;
  355                 while (si->text[i] != ']') {
  356                     if (!si->text[i] || si->text[i] == '\n' || si->text[i] == '\r') {
  357                         goto nexti;
  358                     }
  359                     i++;
  360                 }
  361                 i++;
  362                 if (smbc_get_num(si->text, &i, &position)) {
  363                     goto nexti;
  364                 }
  365                 while (si->text[i] == ' ' || si->text[i] == '\t') i++;
  366                 if (si->text[i] != '/') {
  367                     goto nexti;
  368                 }
  369                 i++;
  370                 if (smbc_get_num(si->text, &i, &total)) {
  371                     goto nexti;
  372                 }
  373                 if (total < c->from) total = c->from;
  374                 c->est_length = total;
  375                 lasti = i;
  376             }
  377         }
  378         if (lasti) memmove(si->text, si->text + lasti, si->ntext -= lasti);
  379     }
  380 }
  381 
  382 static void smb_got_data(struct connection *c)
  383 {
  384     struct smb_connection_info *si = c->info;
  385     unsigned char *buffer = mem_alloc(page_size);
  386     int r;
  387     int a;
  388     if (si->list) {
  389         smb_read_text(c, c->sock1);
  390         mem_free(buffer);
  391         return;
  392     }
  393     EINTRLOOP(r, (int)read(c->sock1, buffer, page_size));
  394     if (r == -1) {
  395         setcstate(c, get_error_from_errno(errno));
  396         retry_connection(c);
  397         mem_free(buffer);
  398         return;
  399     }
  400     if (r == 0) {
  401         mem_free(buffer);
  402         if (!si->cl) {
  403             si->cl = 1;
  404             set_handlers(c->sock1, NULL, NULL, NULL, NULL);
  405             return;
  406         }
  407         end_smb_connection(c);
  408         return;
  409     }
  410     setcstate(c, S_TRANS);
  411     if (!c->cache) {
  412         if (get_cache_entry(c->url, &c->cache)) {
  413             setcstate(c, S_OUT_OF_MEM);
  414             abort_connection(c);
  415             mem_free(buffer);
  416             return;
  417         }
  418         c->cache->refcount--;
  419     }
  420     if ((off_t)(0UL + c->from + r) < 0) {
  421         setcstate(c, S_LARGE_FILE);
  422         abort_connection(c);
  423         mem_free(buffer);
  424         return;
  425     }
  426     c->received += r;
  427     a = add_fragment(c->cache, c->from, buffer, r);
  428     if (a < 0) {
  429         setcstate(c, a);
  430         abort_connection(c);
  431         mem_free(buffer);
  432         return;
  433     }
  434     if (a == 1) c->tries = 0;
  435     c->from += r;
  436     mem_free(buffer);
  437 }
  438 
  439 static void smb_got_text(struct connection *c)
  440 {
  441     smb_read_text(c, c->sock2);
  442 }
  443 
  444 static void end_smb_connection(struct connection *c)
  445 {
  446     struct smb_connection_info *si = c->info;
  447     if (!c->cache) {
  448         if (get_cache_entry(c->url, &c->cache)) {
  449             setcstate(c, S_OUT_OF_MEM);
  450             abort_connection(c);
  451             return;
  452         }
  453         c->cache->refcount--;
  454     }
  455     if (!c->from) {
  456         int sdir;
  457         if (si->ntext && si->text[si->ntext - 1] != '\n') si->text[si->ntext++] = '\n';
  458         si->text[si->ntext] = 0;
  459         if (!strcmp(cast_const_char si->text, CLIENT_NOT_FOUND_STRING "\n")) {
  460             setcstate(c, S_NO_SMB_CLIENT);
  461             if (++si->client < N_CLIENTS) {
  462                 if (si->client > smb_client) smb_client = si->client;
  463                 c->tries = -1;
  464                 retry_connection(c);
  465             } else {
  466                 smb_client = 0;
  467                 abort_connection(c);
  468             }
  469             return;
  470         }
  471         sdir = 0;
  472         if (si->client == SMBC) {
  473             unsigned char *st = si->text;
  474             if (!memcmp(st, "ServerName", 10) && strchr(cast_const_char st, '\n')) st = cast_uchar strchr(cast_const_char st, '\n') + 1;
  475             if (!memcmp(st, "Logged", 6) && strchr(cast_const_char st, '\n')) st = cast_uchar strchr(cast_const_char st, '\n') + 1;
  476             if (!strstr(cast_const_char st, "ERR")) sdir = 1;
  477         }
  478         if (!si->list && *c->url &&
  479             c->url[strlen(cast_const_char c->url) - 1] != '/' &&
  480             c->url[strlen(cast_const_char c->url) - 1] != '\\' &&
  481             (strstr(cast_const_char si->text, "NT_STATUS_FILE_IS_A_DIRECTORY") ||
  482              strstr(cast_const_char si->text, "NT_STATUS_ACCESS_DENIED") ||
  483              strstr(cast_const_char si->text, "ERRbadfile") || sdir)) {
  484             if (c->cache->redirect) mem_free(c->cache->redirect);
  485             c->cache->redirect = stracpy(c->url);
  486             c->cache->redirect_get = 1;
  487             add_to_strn(&c->cache->redirect, cast_uchar "/");
  488             c->cache->incomplete = 0;
  489         } else {
  490             unsigned char *ls, *le, *le2;
  491             unsigned char *ud;
  492             unsigned char *t = init_str();
  493             int l = 0;
  494             int type = 0;
  495             int pos = 0;
  496             int a;
  497             add_to_str(&t, &l, cast_uchar "<html><head><title>");
  498             ud = stracpy(c->url);
  499             if (strchr(cast_const_char ud, POST_CHAR)) *cast_uchar strchr(cast_const_char ud, POST_CHAR) = 0;
  500             add_conv_str(&t, &l, ud, (int)strlen(cast_const_char ud), -1);
  501             mem_free(ud);
  502             add_to_str(&t, &l, cast_uchar "</title></head><body><pre>");
  503             if (si->list == 1 && si->client == SMBC) {
  504 /* smbc has a nasty bug that it writes field descriptions to stderr and data to
  505    stdout. Because of stdout buffer, they'll get mixed in the output. Try to
  506    demix them. */
  507 #define SERVER  "Server              Comment\n------              -------\n"
  508 #define WORKGR  "Workgroup           Master\n---------           ------\n"
  509                 unsigned char *spos = cast_uchar strstr(cast_const_char si->text, SERVER);
  510                 unsigned char *gpos;
  511                 unsigned char *p, *pp, *ppp;
  512                 if (spos) memmove(spos, spos + strlen(SERVER), strlen(cast_const_char spos) - strlen(SERVER) + 1);
  513                 gpos = cast_uchar strstr(cast_const_char si->text, WORKGR);
  514                 if (gpos) memmove(gpos, gpos + strlen(WORKGR), strlen(cast_const_char gpos) - strlen(WORKGR) + 1);
  515                 if (!spos && !gpos) goto sc;
  516                 pp = NULL, ppp = NULL, p = si->text;
  517                 while ((p = cast_uchar strstr(cast_const_char p, "\n\n"))) ppp = pp, pp = p + 2, p++;
  518                 if (!pp) goto sc;
  519                 if (!spos || !gpos) ppp = NULL;
  520                 if (spos) {
  521                     if (!ppp) ppp = pp, pp = NULL;
  522                     memmove(ppp + strlen(SERVER), ppp, strlen(cast_const_char ppp) + 1);
  523                     memcpy(ppp, SERVER, strlen(SERVER));
  524                     if (pp) pp += strlen(SERVER);
  525                 }
  526                 if (gpos && pp) {
  527                     memmove(pp + strlen(WORKGR), pp, strlen(cast_const_char pp) + 1);
  528                     memcpy(pp, WORKGR, strlen(WORKGR));
  529                 }
  530                 goto sc;
  531             }
  532             sc:
  533             ls = si->text;
  534             while ((le = cast_uchar strchr(cast_const_char ls, '\n'))) {
  535                 unsigned char *lx;
  536                 unsigned char *st;
  537                 le2 = cast_uchar strchr(cast_const_char ls, '\r');
  538                 if (!le2 || le2 > le) le2 = le;
  539                 lx = memacpy(ls, le2 - ls);
  540                 if (si->list == 1) {
  541                     unsigned char *ll, *lll;
  542                     if (!*lx) type = 0;
  543                     if (strstr(cast_const_char lx, "Sharename") && (st = cast_uchar strstr(cast_const_char lx, "Type"))) {
  544                         pos = (int)(st - lx);
  545                         type = 1;
  546                         goto af;
  547                     }
  548                     if (strstr(cast_const_char lx, "Server") && strstr(cast_const_char lx, "Comment")) {
  549                         type = 2;
  550                         goto af;
  551                     }
  552                     if (strstr(cast_const_char lx, "Workgroup") && (st = cast_uchar strstr(cast_const_char lx, "Master"))) {
  553                         pos = (int)(st - lx);
  554                         type = 3;
  555                         goto af;
  556                     }
  557                     if (!type) goto af;
  558                     for (ll = lx; *ll; ll++) if (!WHITECHAR(*ll) && *ll != '-') goto np;
  559                     goto af;
  560                     np:
  561                     for (ll = lx; *ll; ll++) if (!WHITECHAR(*ll)) break;
  562                     for (lll = ll; *lll /* && lll[1]*/; lll++) if (WHITECHAR(*lll) /*&& WHITECHAR(lll[1])*/) break;
  563                     if (type == 1) {
  564                         unsigned char *llll;
  565                         if (!strstr(cast_const_char lll, "Disk")) goto af;
  566                         if (pos && (size_t)pos < strlen(cast_const_char lx) && WHITECHAR(*(llll = lx + pos - 1)) && llll > ll) {
  567                             while (llll > ll && WHITECHAR(*llll)) llll--;
  568                             if (!WHITECHAR(*llll)) lll = llll + 1;
  569                         }
  570                         add_conv_str(&t, &l, lx, (int)(ll - lx), 0);
  571                         add_to_str(&t, &l, cast_uchar "<a href=\"/");
  572                         add_conv_str(&t, &l, ll, (int)(lll - ll), 1);
  573                         add_to_str(&t, &l, cast_uchar "/\">");
  574                         add_conv_str(&t, &l, ll, (int)(lll - ll), 0);
  575                         add_to_str(&t, &l, cast_uchar "</a>");
  576                         add_conv_str(&t, &l, lll, (int)strlen(cast_const_char lll), 0);
  577                     } else if (type == 2) {
  578                         sss:
  579                         add_conv_str(&t, &l, lx, (int)(ll - lx), 0);
  580                         add_to_str(&t, &l, cast_uchar "<a href=\"smb://");
  581                         add_conv_str(&t, &l, ll, (int)(lll - ll), 1);
  582                         add_to_str(&t, &l, cast_uchar "/\">");
  583                         add_conv_str(&t, &l, ll, (int)(lll - ll), 0);
  584                         add_to_str(&t, &l, cast_uchar "</a>");
  585                         add_conv_str(&t, &l, lll, (int)strlen(cast_const_char lll), 0);
  586                     } else if (type == 3) {
  587                         if ((size_t)pos < strlen(cast_const_char lx) && pos && WHITECHAR(lx[pos - 1]) && !WHITECHAR(lx[pos])) ll = lx + pos;
  588                         else for (ll = lll; *ll; ll++) if (!WHITECHAR(*ll)) break;
  589                         for (lll = ll; *lll; lll++) if (WHITECHAR(*lll)) break;
  590                         goto sss;
  591                     } else goto af;
  592                 } else if (si->list == 2 && si->client == SMBCLIENT) {
  593                     if (strstr(cast_const_char lx, "NT_STATUS")) {
  594                         le[1] = 0;
  595                         goto af;
  596                     }
  597                     if (le2 - ls >= 5 && ls[0] == ' ' && ls[1] == ' ' && ls[2] != ' ') {
  598                         int dir;
  599                         unsigned char *pp;
  600                         unsigned char *p = ls + 3;
  601                         while (le2 - p >= 2) {
  602                             if (p[0] == ' ' && p[1] == ' ') goto o;
  603                             p++;
  604                         }
  605                         goto af;
  606                         o:
  607                         dir = 0;
  608                         pp = p;
  609                         while (pp < le2 && *pp == ' ') pp++;
  610                         while (pp < le2 && *pp != ' ') {
  611                             if (*pp == 'D') {
  612                                 dir = 1;
  613                                 break;
  614                             }
  615                             pp++;
  616                         }
  617                         add_to_str(&t, &l, cast_uchar "  <a href=\"./");
  618                         add_conv_str(&t, &l, ls + 2, (int)(p - (ls + 2)), 1);
  619                         if (dir) add_chr_to_str(&t, &l, '/');
  620                         add_to_str(&t, &l, cast_uchar "\">");
  621                         add_conv_str(&t, &l, ls + 2, (int)(p - (ls + 2)), 0);
  622                         add_to_str(&t, &l, cast_uchar "</a>");
  623                         add_conv_str(&t, &l, p, (int)(le - p), 0);
  624                     } else goto af;
  625                 } else if (si->list == 2 && si->client == SMBC) {
  626                     unsigned char *d;
  627                     if (le2 - ls <= 17) goto af;
  628                     d = ls + 17;
  629                     smbc_next_chr:
  630                     if (d + 9 >= le2) goto af;
  631                     if (!(d[0] == ':' && d[1] >= '0' && d[1] <= '9' && d[2] >= '0' && d[2] <= '9' && d[3] == ' ' && ((d[4] == '1' && d[5] == '9') || (d[4] == '2' && d[5] >= '0' && d[5] <= '9')) && d[6] >= '0' && d[6] <= '9' && d[7] >= '0' && d[7] <= '9' && d[8] == ' ')) {
  632                         d++;
  633                         goto smbc_next_chr;
  634                     }
  635                     d += 9;
  636                     add_conv_str(&t, &l, ls, (int)(d - ls), 0);
  637                     add_to_str(&t, &l, cast_uchar "<a href=\"./");
  638                     add_conv_str(&t, &l, d, (int)(le2 - d), 1);
  639                     if (ls[4] == 'D') add_chr_to_str(&t, &l, '/');
  640                     add_to_str(&t, &l, cast_uchar "\">");
  641                     add_conv_str(&t, &l, d, (int)(le2 - d), 0);
  642                     add_to_str(&t, &l, cast_uchar "</a>");
  643                 } else af: add_conv_str(&t, &l, ls, (int)(le2 - ls), 0);
  644                 add_chr_to_str(&t, &l, '\n');
  645                 ls = le + 1;
  646                 mem_free(lx);
  647             }
  648             /*add_to_str(&t, &l, si->text);*/
  649             a = add_fragment(c->cache, 0, t, l);
  650             if (a < 0) {
  651                 mem_free(t);
  652                 setcstate(c, a);
  653                 abort_connection(c);
  654                 return;
  655             }
  656             c->from += l;
  657             truncate_entry(c->cache, l, 1);
  658             c->cache->incomplete = 0;
  659             mem_free(t);
  660             if (!c->cache->head) c->cache->head = stracpy(cast_uchar "\r\n");
  661             add_to_strn(&c->cache->head, cast_uchar "Content-Type: text/html\r\n");
  662         }
  663     } else {
  664         truncate_entry(c->cache, c->from, 1);
  665         c->cache->incomplete = 0;
  666     }
  667     close_socket(&c->sock1);
  668     close_socket(&c->sock2);
  669     setcstate(c, S__OK);
  670     abort_connection(c);
  671     return;
  672 }
  673 
  674 #endif