"Fossies" - the Fresh Open Source Software Archive

Member "links-1.03/smb.c" (16 Oct 2011, 17501 Bytes) of archive /linux/www/links-1.03.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: 2.8_vs_1.03.

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