12439e4bfSJean-Christophe PLAGNIOL-VILLARD /* 22439e4bfSJean-Christophe PLAGNIOL-VILLARD * (C) Copyright 2004 32439e4bfSJean-Christophe PLAGNIOL-VILLARD * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 42439e4bfSJean-Christophe PLAGNIOL-VILLARD * 52439e4bfSJean-Christophe PLAGNIOL-VILLARD * See file CREDITS for list of people who contributed to this 62439e4bfSJean-Christophe PLAGNIOL-VILLARD * project. 72439e4bfSJean-Christophe PLAGNIOL-VILLARD * 82439e4bfSJean-Christophe PLAGNIOL-VILLARD * This program is free software; you can redistribute it and/or 92439e4bfSJean-Christophe PLAGNIOL-VILLARD * modify it under the terms of the GNU General Public License as 102439e4bfSJean-Christophe PLAGNIOL-VILLARD * published by the Free Software Foundation; either version 2 of 112439e4bfSJean-Christophe PLAGNIOL-VILLARD * the License, or (at your option) any later version. 122439e4bfSJean-Christophe PLAGNIOL-VILLARD * 132439e4bfSJean-Christophe PLAGNIOL-VILLARD * This program is distributed in the hope that it will be useful, 142439e4bfSJean-Christophe PLAGNIOL-VILLARD * but WITHOUT ANY WARRANTY; without even the implied warranty of 152439e4bfSJean-Christophe PLAGNIOL-VILLARD * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 162439e4bfSJean-Christophe PLAGNIOL-VILLARD * GNU General Public License for more details. 172439e4bfSJean-Christophe PLAGNIOL-VILLARD * 182439e4bfSJean-Christophe PLAGNIOL-VILLARD * You should have received a copy of the GNU General Public License 192439e4bfSJean-Christophe PLAGNIOL-VILLARD * along with this program; if not, write to the Free Software 202439e4bfSJean-Christophe PLAGNIOL-VILLARD * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 212439e4bfSJean-Christophe PLAGNIOL-VILLARD * MA 02111-1307 USA 222439e4bfSJean-Christophe PLAGNIOL-VILLARD */ 232439e4bfSJean-Christophe PLAGNIOL-VILLARD 242439e4bfSJean-Christophe PLAGNIOL-VILLARD #include <common.h> 252439e4bfSJean-Christophe PLAGNIOL-VILLARD #include <command.h> 2652cb4d4fSJean-Christophe PLAGNIOL-VILLARD #include <stdio_dev.h> 272439e4bfSJean-Christophe PLAGNIOL-VILLARD #include <net.h> 282439e4bfSJean-Christophe PLAGNIOL-VILLARD 292439e4bfSJean-Christophe PLAGNIOL-VILLARD DECLARE_GLOBAL_DATA_PTR; 302439e4bfSJean-Christophe PLAGNIOL-VILLARD 312439e4bfSJean-Christophe PLAGNIOL-VILLARD static char input_buffer[512]; 322439e4bfSJean-Christophe PLAGNIOL-VILLARD static int input_size = 0; /* char count in input buffer */ 332439e4bfSJean-Christophe PLAGNIOL-VILLARD static int input_offset = 0; /* offset to valid chars in input buffer */ 342439e4bfSJean-Christophe PLAGNIOL-VILLARD static int input_recursion = 0; 352439e4bfSJean-Christophe PLAGNIOL-VILLARD static int output_recursion = 0; 362439e4bfSJean-Christophe PLAGNIOL-VILLARD static int net_timeout; 372439e4bfSJean-Christophe PLAGNIOL-VILLARD static uchar nc_ether[6]; /* server enet address */ 382439e4bfSJean-Christophe PLAGNIOL-VILLARD static IPaddr_t nc_ip; /* server ip */ 392439e4bfSJean-Christophe PLAGNIOL-VILLARD static short nc_port; /* source/target port */ 402439e4bfSJean-Christophe PLAGNIOL-VILLARD static const char *output_packet; /* used by first send udp */ 412439e4bfSJean-Christophe PLAGNIOL-VILLARD static int output_packet_len = 0; 422439e4bfSJean-Christophe PLAGNIOL-VILLARD 4303eb129fSLuca Ceresoli static void nc_wait_arp_handler(uchar *pkt, unsigned dest, 4403eb129fSLuca Ceresoli IPaddr_t sip, unsigned src, 452439e4bfSJean-Christophe PLAGNIOL-VILLARD unsigned len) 462439e4bfSJean-Christophe PLAGNIOL-VILLARD { 472439e4bfSJean-Christophe PLAGNIOL-VILLARD NetState = NETLOOP_SUCCESS; /* got arp reply - quit net loop */ 482439e4bfSJean-Christophe PLAGNIOL-VILLARD } 492439e4bfSJean-Christophe PLAGNIOL-VILLARD 5003eb129fSLuca Ceresoli static void nc_handler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, 512439e4bfSJean-Christophe PLAGNIOL-VILLARD unsigned len) 522439e4bfSJean-Christophe PLAGNIOL-VILLARD { 532439e4bfSJean-Christophe PLAGNIOL-VILLARD if (input_size) 542439e4bfSJean-Christophe PLAGNIOL-VILLARD NetState = NETLOOP_SUCCESS; /* got input - quit net loop */ 552439e4bfSJean-Christophe PLAGNIOL-VILLARD } 562439e4bfSJean-Christophe PLAGNIOL-VILLARD 572439e4bfSJean-Christophe PLAGNIOL-VILLARD static void nc_timeout (void) 582439e4bfSJean-Christophe PLAGNIOL-VILLARD { 592439e4bfSJean-Christophe PLAGNIOL-VILLARD NetState = NETLOOP_SUCCESS; 602439e4bfSJean-Christophe PLAGNIOL-VILLARD } 612439e4bfSJean-Christophe PLAGNIOL-VILLARD 622439e4bfSJean-Christophe PLAGNIOL-VILLARD void NcStart (void) 632439e4bfSJean-Christophe PLAGNIOL-VILLARD { 642439e4bfSJean-Christophe PLAGNIOL-VILLARD if (!output_packet_len || memcmp (nc_ether, NetEtherNullAddr, 6)) { 652439e4bfSJean-Christophe PLAGNIOL-VILLARD /* going to check for input packet */ 662439e4bfSJean-Christophe PLAGNIOL-VILLARD NetSetHandler (nc_handler); 672439e4bfSJean-Christophe PLAGNIOL-VILLARD NetSetTimeout (net_timeout, nc_timeout); 682439e4bfSJean-Christophe PLAGNIOL-VILLARD } else { 692439e4bfSJean-Christophe PLAGNIOL-VILLARD /* send arp request */ 702439e4bfSJean-Christophe PLAGNIOL-VILLARD uchar *pkt; 712439e4bfSJean-Christophe PLAGNIOL-VILLARD NetSetHandler (nc_wait_arp_handler); 722439e4bfSJean-Christophe PLAGNIOL-VILLARD pkt = (uchar *) NetTxPacket + NetEthHdrSize () + IP_HDR_SIZE; 732439e4bfSJean-Christophe PLAGNIOL-VILLARD memcpy (pkt, output_packet, output_packet_len); 742439e4bfSJean-Christophe PLAGNIOL-VILLARD NetSendUDPPacket (nc_ether, nc_ip, nc_port, nc_port, output_packet_len); 752439e4bfSJean-Christophe PLAGNIOL-VILLARD } 762439e4bfSJean-Christophe PLAGNIOL-VILLARD } 772439e4bfSJean-Christophe PLAGNIOL-VILLARD 782439e4bfSJean-Christophe PLAGNIOL-VILLARD int nc_input_packet (uchar * pkt, unsigned dest, unsigned src, unsigned len) 792439e4bfSJean-Christophe PLAGNIOL-VILLARD { 802439e4bfSJean-Christophe PLAGNIOL-VILLARD int end, chunk; 812439e4bfSJean-Christophe PLAGNIOL-VILLARD 822439e4bfSJean-Christophe PLAGNIOL-VILLARD if (dest != nc_port || !len) 832439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; /* not for us */ 842439e4bfSJean-Christophe PLAGNIOL-VILLARD 852439e4bfSJean-Christophe PLAGNIOL-VILLARD if (input_size == sizeof input_buffer) 862439e4bfSJean-Christophe PLAGNIOL-VILLARD return 1; /* no space */ 872439e4bfSJean-Christophe PLAGNIOL-VILLARD if (len > sizeof input_buffer - input_size) 882439e4bfSJean-Christophe PLAGNIOL-VILLARD len = sizeof input_buffer - input_size; 892439e4bfSJean-Christophe PLAGNIOL-VILLARD 902439e4bfSJean-Christophe PLAGNIOL-VILLARD end = input_offset + input_size; 912439e4bfSJean-Christophe PLAGNIOL-VILLARD if (end > sizeof input_buffer) 922439e4bfSJean-Christophe PLAGNIOL-VILLARD end -= sizeof input_buffer; 932439e4bfSJean-Christophe PLAGNIOL-VILLARD 942439e4bfSJean-Christophe PLAGNIOL-VILLARD chunk = len; 952439e4bfSJean-Christophe PLAGNIOL-VILLARD if (end + len > sizeof input_buffer) { 962439e4bfSJean-Christophe PLAGNIOL-VILLARD chunk = sizeof input_buffer - end; 972439e4bfSJean-Christophe PLAGNIOL-VILLARD memcpy(input_buffer, pkt + chunk, len - chunk); 982439e4bfSJean-Christophe PLAGNIOL-VILLARD } 992439e4bfSJean-Christophe PLAGNIOL-VILLARD memcpy (input_buffer + end, pkt, chunk); 1002439e4bfSJean-Christophe PLAGNIOL-VILLARD 1012439e4bfSJean-Christophe PLAGNIOL-VILLARD input_size += len; 1022439e4bfSJean-Christophe PLAGNIOL-VILLARD 1032439e4bfSJean-Christophe PLAGNIOL-VILLARD return 1; 1042439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1052439e4bfSJean-Christophe PLAGNIOL-VILLARD 1062439e4bfSJean-Christophe PLAGNIOL-VILLARD static void nc_send_packet (const char *buf, int len) 1072439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1082439e4bfSJean-Christophe PLAGNIOL-VILLARD struct eth_device *eth; 1092439e4bfSJean-Christophe PLAGNIOL-VILLARD int inited = 0; 1102439e4bfSJean-Christophe PLAGNIOL-VILLARD uchar *pkt; 1112439e4bfSJean-Christophe PLAGNIOL-VILLARD uchar *ether; 1122439e4bfSJean-Christophe PLAGNIOL-VILLARD IPaddr_t ip; 1132439e4bfSJean-Christophe PLAGNIOL-VILLARD 1142439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((eth = eth_get_dev ()) == NULL) { 1152439e4bfSJean-Christophe PLAGNIOL-VILLARD return; 1162439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1172439e4bfSJean-Christophe PLAGNIOL-VILLARD 1182439e4bfSJean-Christophe PLAGNIOL-VILLARD if (!memcmp (nc_ether, NetEtherNullAddr, 6)) { 1192439e4bfSJean-Christophe PLAGNIOL-VILLARD if (eth->state == ETH_STATE_ACTIVE) 1202439e4bfSJean-Christophe PLAGNIOL-VILLARD return; /* inside net loop */ 1212439e4bfSJean-Christophe PLAGNIOL-VILLARD output_packet = buf; 1222439e4bfSJean-Christophe PLAGNIOL-VILLARD output_packet_len = len; 1232439e4bfSJean-Christophe PLAGNIOL-VILLARD NetLoop (NETCONS); /* wait for arp reply and send packet */ 1242439e4bfSJean-Christophe PLAGNIOL-VILLARD output_packet_len = 0; 1252439e4bfSJean-Christophe PLAGNIOL-VILLARD return; 1262439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1272439e4bfSJean-Christophe PLAGNIOL-VILLARD 1282439e4bfSJean-Christophe PLAGNIOL-VILLARD if (eth->state != ETH_STATE_ACTIVE) { 1292439e4bfSJean-Christophe PLAGNIOL-VILLARD if (eth_init (gd->bd) < 0) 1302439e4bfSJean-Christophe PLAGNIOL-VILLARD return; 1312439e4bfSJean-Christophe PLAGNIOL-VILLARD inited = 1; 1322439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1332439e4bfSJean-Christophe PLAGNIOL-VILLARD pkt = (uchar *) NetTxPacket + NetEthHdrSize () + IP_HDR_SIZE; 1342439e4bfSJean-Christophe PLAGNIOL-VILLARD memcpy (pkt, buf, len); 1352439e4bfSJean-Christophe PLAGNIOL-VILLARD ether = nc_ether; 1362439e4bfSJean-Christophe PLAGNIOL-VILLARD ip = nc_ip; 1372439e4bfSJean-Christophe PLAGNIOL-VILLARD NetSendUDPPacket (ether, ip, nc_port, nc_port, len); 1382439e4bfSJean-Christophe PLAGNIOL-VILLARD 1392439e4bfSJean-Christophe PLAGNIOL-VILLARD if (inited) 1402439e4bfSJean-Christophe PLAGNIOL-VILLARD eth_halt (); 1412439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1422439e4bfSJean-Christophe PLAGNIOL-VILLARD 143fa2744deSMike Frysinger static int nc_start(void) 1442439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1452439e4bfSJean-Christophe PLAGNIOL-VILLARD int netmask, our_ip; 1462439e4bfSJean-Christophe PLAGNIOL-VILLARD 1472439e4bfSJean-Christophe PLAGNIOL-VILLARD nc_port = 6666; /* default port */ 1482439e4bfSJean-Christophe PLAGNIOL-VILLARD 1492439e4bfSJean-Christophe PLAGNIOL-VILLARD if (getenv ("ncip")) { 1502439e4bfSJean-Christophe PLAGNIOL-VILLARD char *p; 1512439e4bfSJean-Christophe PLAGNIOL-VILLARD 1522439e4bfSJean-Christophe PLAGNIOL-VILLARD nc_ip = getenv_IPaddr ("ncip"); 1532439e4bfSJean-Christophe PLAGNIOL-VILLARD if (!nc_ip) 1542439e4bfSJean-Christophe PLAGNIOL-VILLARD return -1; /* ncip is 0.0.0.0 */ 1552439e4bfSJean-Christophe PLAGNIOL-VILLARD if ((p = strchr (getenv ("ncip"), ':')) != NULL) 1562439e4bfSJean-Christophe PLAGNIOL-VILLARD nc_port = simple_strtoul (p + 1, NULL, 10); 1572439e4bfSJean-Christophe PLAGNIOL-VILLARD } else 1582439e4bfSJean-Christophe PLAGNIOL-VILLARD nc_ip = ~0; /* ncip is not set */ 1592439e4bfSJean-Christophe PLAGNIOL-VILLARD 1602439e4bfSJean-Christophe PLAGNIOL-VILLARD our_ip = getenv_IPaddr ("ipaddr"); 1612439e4bfSJean-Christophe PLAGNIOL-VILLARD netmask = getenv_IPaddr ("netmask"); 1622439e4bfSJean-Christophe PLAGNIOL-VILLARD 1632439e4bfSJean-Christophe PLAGNIOL-VILLARD if (nc_ip == ~0 || /* 255.255.255.255 */ 1642439e4bfSJean-Christophe PLAGNIOL-VILLARD ((netmask & our_ip) == (netmask & nc_ip) && /* on the same net */ 1652439e4bfSJean-Christophe PLAGNIOL-VILLARD (netmask | nc_ip) == ~0)) /* broadcast to our net */ 1662439e4bfSJean-Christophe PLAGNIOL-VILLARD memset (nc_ether, 0xff, sizeof nc_ether); 1672439e4bfSJean-Christophe PLAGNIOL-VILLARD else 1682439e4bfSJean-Christophe PLAGNIOL-VILLARD memset (nc_ether, 0, sizeof nc_ether); /* force arp request */ 1692439e4bfSJean-Christophe PLAGNIOL-VILLARD 1702439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 1712439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1722439e4bfSJean-Christophe PLAGNIOL-VILLARD 173fa2744deSMike Frysinger static void nc_putc(char c) 1742439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1752439e4bfSJean-Christophe PLAGNIOL-VILLARD if (output_recursion) 1762439e4bfSJean-Christophe PLAGNIOL-VILLARD return; 1772439e4bfSJean-Christophe PLAGNIOL-VILLARD output_recursion = 1; 1782439e4bfSJean-Christophe PLAGNIOL-VILLARD 1792439e4bfSJean-Christophe PLAGNIOL-VILLARD nc_send_packet (&c, 1); 1802439e4bfSJean-Christophe PLAGNIOL-VILLARD 1812439e4bfSJean-Christophe PLAGNIOL-VILLARD output_recursion = 0; 1822439e4bfSJean-Christophe PLAGNIOL-VILLARD } 1832439e4bfSJean-Christophe PLAGNIOL-VILLARD 184fa2744deSMike Frysinger static void nc_puts(const char *s) 1852439e4bfSJean-Christophe PLAGNIOL-VILLARD { 1862439e4bfSJean-Christophe PLAGNIOL-VILLARD int len; 1872439e4bfSJean-Christophe PLAGNIOL-VILLARD 1882439e4bfSJean-Christophe PLAGNIOL-VILLARD if (output_recursion) 1892439e4bfSJean-Christophe PLAGNIOL-VILLARD return; 1902439e4bfSJean-Christophe PLAGNIOL-VILLARD output_recursion = 1; 1912439e4bfSJean-Christophe PLAGNIOL-VILLARD 192*1a9845b4SMichael Walle len = strlen(s); 193*1a9845b4SMichael Walle while (len) { 194*1a9845b4SMichael Walle int send_len = min(len, 512); 195*1a9845b4SMichael Walle nc_send_packet(s, send_len); 196*1a9845b4SMichael Walle len -= send_len; 197*1a9845b4SMichael Walle s += send_len; 198*1a9845b4SMichael Walle } 1992439e4bfSJean-Christophe PLAGNIOL-VILLARD 2002439e4bfSJean-Christophe PLAGNIOL-VILLARD output_recursion = 0; 2012439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2022439e4bfSJean-Christophe PLAGNIOL-VILLARD 203fa2744deSMike Frysinger static int nc_getc(void) 2042439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2052439e4bfSJean-Christophe PLAGNIOL-VILLARD uchar c; 2062439e4bfSJean-Christophe PLAGNIOL-VILLARD 2072439e4bfSJean-Christophe PLAGNIOL-VILLARD input_recursion = 1; 2082439e4bfSJean-Christophe PLAGNIOL-VILLARD 2092439e4bfSJean-Christophe PLAGNIOL-VILLARD net_timeout = 0; /* no timeout */ 2102439e4bfSJean-Christophe PLAGNIOL-VILLARD while (!input_size) 2112439e4bfSJean-Christophe PLAGNIOL-VILLARD NetLoop (NETCONS); 2122439e4bfSJean-Christophe PLAGNIOL-VILLARD 2132439e4bfSJean-Christophe PLAGNIOL-VILLARD input_recursion = 0; 2142439e4bfSJean-Christophe PLAGNIOL-VILLARD 2152439e4bfSJean-Christophe PLAGNIOL-VILLARD c = input_buffer[input_offset++]; 2162439e4bfSJean-Christophe PLAGNIOL-VILLARD 2172439e4bfSJean-Christophe PLAGNIOL-VILLARD if (input_offset >= sizeof input_buffer) 2182439e4bfSJean-Christophe PLAGNIOL-VILLARD input_offset -= sizeof input_buffer; 2192439e4bfSJean-Christophe PLAGNIOL-VILLARD input_size--; 2202439e4bfSJean-Christophe PLAGNIOL-VILLARD 2212439e4bfSJean-Christophe PLAGNIOL-VILLARD return c; 2222439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2232439e4bfSJean-Christophe PLAGNIOL-VILLARD 224fa2744deSMike Frysinger static int nc_tstc(void) 2252439e4bfSJean-Christophe PLAGNIOL-VILLARD { 2262439e4bfSJean-Christophe PLAGNIOL-VILLARD struct eth_device *eth; 2272439e4bfSJean-Christophe PLAGNIOL-VILLARD 2282439e4bfSJean-Christophe PLAGNIOL-VILLARD if (input_recursion) 2292439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; 2302439e4bfSJean-Christophe PLAGNIOL-VILLARD 2312439e4bfSJean-Christophe PLAGNIOL-VILLARD if (input_size) 2322439e4bfSJean-Christophe PLAGNIOL-VILLARD return 1; 2332439e4bfSJean-Christophe PLAGNIOL-VILLARD 2342439e4bfSJean-Christophe PLAGNIOL-VILLARD eth = eth_get_dev (); 2352439e4bfSJean-Christophe PLAGNIOL-VILLARD if (eth && eth->state == ETH_STATE_ACTIVE) 2362439e4bfSJean-Christophe PLAGNIOL-VILLARD return 0; /* inside net loop */ 2372439e4bfSJean-Christophe PLAGNIOL-VILLARD 2382439e4bfSJean-Christophe PLAGNIOL-VILLARD input_recursion = 1; 2392439e4bfSJean-Christophe PLAGNIOL-VILLARD 2402439e4bfSJean-Christophe PLAGNIOL-VILLARD net_timeout = 1; 2412439e4bfSJean-Christophe PLAGNIOL-VILLARD NetLoop (NETCONS); /* kind of poll */ 2422439e4bfSJean-Christophe PLAGNIOL-VILLARD 2432439e4bfSJean-Christophe PLAGNIOL-VILLARD input_recursion = 0; 2442439e4bfSJean-Christophe PLAGNIOL-VILLARD 2452439e4bfSJean-Christophe PLAGNIOL-VILLARD return input_size != 0; 2462439e4bfSJean-Christophe PLAGNIOL-VILLARD } 2472439e4bfSJean-Christophe PLAGNIOL-VILLARD 2482439e4bfSJean-Christophe PLAGNIOL-VILLARD int drv_nc_init (void) 2492439e4bfSJean-Christophe PLAGNIOL-VILLARD { 25052cb4d4fSJean-Christophe PLAGNIOL-VILLARD struct stdio_dev dev; 2512439e4bfSJean-Christophe PLAGNIOL-VILLARD int rc; 2522439e4bfSJean-Christophe PLAGNIOL-VILLARD 2532439e4bfSJean-Christophe PLAGNIOL-VILLARD memset (&dev, 0, sizeof (dev)); 2542439e4bfSJean-Christophe PLAGNIOL-VILLARD 2552439e4bfSJean-Christophe PLAGNIOL-VILLARD strcpy (dev.name, "nc"); 2562439e4bfSJean-Christophe PLAGNIOL-VILLARD dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; 2572439e4bfSJean-Christophe PLAGNIOL-VILLARD dev.start = nc_start; 2582439e4bfSJean-Christophe PLAGNIOL-VILLARD dev.putc = nc_putc; 2592439e4bfSJean-Christophe PLAGNIOL-VILLARD dev.puts = nc_puts; 2602439e4bfSJean-Christophe PLAGNIOL-VILLARD dev.getc = nc_getc; 2612439e4bfSJean-Christophe PLAGNIOL-VILLARD dev.tstc = nc_tstc; 2622439e4bfSJean-Christophe PLAGNIOL-VILLARD 26352cb4d4fSJean-Christophe PLAGNIOL-VILLARD rc = stdio_register (&dev); 2642439e4bfSJean-Christophe PLAGNIOL-VILLARD 2652439e4bfSJean-Christophe PLAGNIOL-VILLARD return (rc == 0) ? 1 : rc; 2662439e4bfSJean-Christophe PLAGNIOL-VILLARD } 267