PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
netcnf.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright ps2dev - http://www.ps2dev.org
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9*/
10
11#ifdef _IOP
12#include "irx_imports.h"
13#else
14#include <ctype.h>
15#include <fcntl.h>
16#include <stdarg.h>
17#include <stdint.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <sys/stat.h>
22#include <sys/statvfs.h>
23#include <unistd.h>
24typedef int8_t s8;
25typedef int16_t s16;
26typedef int32_t s32;
27typedef intptr_t siptr;
28typedef uint8_t u8;
29typedef uint16_t u16;
30typedef uint32_t u32;
31typedef uintptr_t uiptr;
32#define iomanX_rename(old, new) rename(old, new)
33#define iomanX_sync(...) 0
34typedef struct
35{
36 unsigned int mode;
37 unsigned int attr;
38 unsigned int size;
39 unsigned char ctime[8];
40 unsigned char atime[8];
41 unsigned char mtime[8];
42 unsigned int hisize;
43 unsigned int private_0;
44 unsigned int private_1;
45 unsigned int private_2;
46 unsigned int private_3;
47 unsigned int private_4;
48 unsigned int private_5;
50typedef struct
51{
52 iox_stat_t stat;
53 char name[256];
54 void *privdata;
56#endif
57#include <errno.h>
58#include <netcnf.h>
59
60#ifdef _IOP
61IRX_ID("NET_configuration", 2, 30);
62#endif
63// Based on the module from SCE SDK 3.1.0.
64
66{
67 int m_fd;
68 char m_device[16];
69 char m_pathname[256];
70 void *m_buf;
71 int m_filesize;
72 int m_bufpos;
73 int m_allocstate;
74};
75
77{
78 int m_type;
79 int m_offset;
80 const char *m_key;
81};
82
83static void do_init_xor_magic(const char *in_id_buf);
84static int magic_shift_write_netcnf_2(int inshft, int buflen);
85static int magic_shift_read_netcnf_2(int inshft, int buflen);
86static int magic_shift_write_netcnf_1(int inshft, int buflen);
87static int magic_shift_read_netcnf_1(int inshft, int buflen);
88static int do_check_capacity_inner(const char *fpath);
89static int do_get_count_list_inner(const char *fname, int type, sceNetCnfList_t *p);
90static int do_load_entry_inner(const char *fname, int type, const char *usr_name, sceNetCnfEnv_t *e);
91static int do_add_entry_inner(
92 const char *fname,
93 int type,
94 const char *usr_name,
96 const char *icon_value,
97 const char *iconsys_value,
98 int no_check_capacity);
99static int do_edit_entry_inner(
100 const char *fname,
101 int type,
102 const char *usr_name,
103 const char *new_usr_name,
105 const char *icon_value,
106 const char *iconsys_value,
107 int no_check_capacity);
108static int do_delete_entry_inner(
109 const char *fname,
110 int type,
111 const char *usr_name,
112 const char *icon_value,
113 const char *iconsys_value,
114 int no_check_capacity);
115static int do_set_latest_entry_inner(const char *fname, int type, const char *usr_name);
116static int do_delete_all_inner(const char *dev);
117static int do_check_special_provider_inner(const char *fname, int type, const char *usr_name, sceNetCnfEnv_t *e);
118static char *do_alloc_mem_inner(sceNetCnfEnv_t *e, unsigned int size, int align);
119static void do_init_ifc_inner(sceNetCnfInterface_t *ifc);
120static int do_merge_conf_inner(sceNetCnfEnv_t *e);
121static int do_load_conf_inner(sceNetCnfEnv_t *e);
122static int do_load_dial_inner(sceNetCnfEnv_t *e, sceNetCnfPair_t *pair);
123static int do_export_netcnf(sceNetCnfEnv_t *e);
124static void do_address_to_string_inner(char *dst, unsigned int srcint);
125static int do_name_2_address_inner(unsigned int *dst, const char *buf);
126static int do_conv_a2s_inner(char *sp_, char *dp_, int len);
127static int do_conv_s2a_inner(char *sp_, char *dp_, int len);
128static int do_read_check_netcnf(const char *netcnf_path, int type, int no_check_magic, int no_decode);
129static int do_check_provider_inner(const sceNetCnfEnv_t *e, int type);
130static const char *do_handle_netcnf_dirname(const char *fpath, const char *entry_buffer, char *netcnf_file_path);
131static int do_open_netcnf(const char *netcnf_path, int file_flags, int file_mode);
132static int do_readfile_netcnf(int fd, void *ptr, int size);
133static int do_write_netcnf_no_encode(int fd, void *ptr, int size);
134static int do_dopen_wrap(const char *fn);
135static int do_dread_wrap(int fn, iox_dirent_t *buf);
136static int do_remove_wrap(const char *fn);
137static void do_close_netcnf(int fd);
138static void do_dclose_wrap(int fd);
139static int do_filesize_netcnf(int fd);
140static void do_getstat_wrap(const char *fn, iox_stat_t *stx);
141static void do_chstat_mode_copyprotect_wrap(const char *fn);
142static void do_set_callback_inner(sceNetCnfCallback_t *pcallback);
143#ifdef _IOP
144static int do_init_heap(void);
145#endif
146static void *do_alloc_heapmem(int nbytes);
147static void do_free_heapmem(void *ptr);
148#ifdef _IOP
149static void do_delete_heap(void);
150#endif
151
152#ifdef _IOP
153extern struct irx_export_table _exp_netcnf;
154#endif
155// Unofficial: move to bss
156static int g_no_check_capacity;
157// Unofficial: move to bss
158static int g_no_check_provider;
159// Unofficial: move to bss
160static u32 g_id_result;
161// Unofficial: move to bss
162static char *g_count_list_heapptr;
163// Unofficial: move to bss
164static char *g_load_entry_heapptr;
165// Unofficial: move to bss
166static char *g_add_entry_heapptr;
167// Unofficial: move to bss
168static char *g_edit_entry_heapptr;
169// Unofficial: move to bss
170static char *g_delete_entry_heapptr;
171// Unofficial: move to bss
172static char *g_set_latest_entry_heapptr;
173// Unofficial: move to bss
174static char *g_check_special_provider_heapptr;
175static const struct netcnf_option g_options_net_cnf[] = {
176 {112, 12, "chat_additional"},
177 {52, 16, "redial_count"},
178 {52, 20, "redial_interval"},
179 {112, 24, "outside_number"},
180 {112, 28, "outside_delay"},
181 {68, 32, "dialing_type"},
182 {0, 0, NULL}};
183static const struct netcnf_option g_options_attach_cnf[] = {
184 {84, 0, "type"},
185 {112, 4, "vendor"},
186 {112, 8, "product"},
187 {112, 12, "location"},
188 {98, 16, "dhcp"},
189 {112, 20, "dhcp_host_name"},
190 {98, 24, "dhcp_host_name_null_terminated"},
191 {98, 25, "dhcp_release_on_stop"},
192 {112, 28, "address"},
193 {112, 32, "netmask"},
194 {112, 36, "chat_additional"},
195 {52, 40, "redial_count"},
196 {52, 44, "redial_interval"},
197 {112, 48, "outside_number"},
198 {112, 52, "outside_delay"},
199 {98, 96, "answer_mode"},
200 {52, 100, "answer_timeout"},
201 {68, 104, "dialing_type"},
202 {112, 108, "chat_login"},
203 {112, 112, "auth_name"},
204 {112, 116, "auth_key"},
205 {112, 120, "peer_name"},
206 {112, 124, "peer_key"},
207 {52, 128, "lcp_timeout"},
208 {52, 132, "ipcp_timeout"},
209 {52, 136, "idle_timeout"},
210 {52, 140, "connect_timeout"},
211 {98, 144, "want.mru_nego"},
212 {98, 145, "want.accm_nego"},
213 {98, 146, "want.magic_nego"},
214 {98, 147, "want.prc_nego"},
215 {98, 148, "want.acc_nego"},
216 {98, 149, "want.address_nego"},
217 {98, 150, "want.vjcomp_nego"},
218 {98, 151, "want.dns1_nego"},
219 {98, 152, "want.dns2_nego"},
220 {77, 160, "want.mru"},
221 {67, 164, "want.accm"},
222 {65, 168, "want.auth"},
223 {112, 172, "want.ip_address"},
224 {112, 176, "want.ip_mask"},
225 {112, 180, "want.dns1"},
226 {112, 184, "want.dns2"},
227 {98, 220, "allow.mru_nego"},
228 {98, 221, "allow.accm_nego"},
229 {98, 222, "allow.magic_nego"},
230 {98, 223, "allow.prc_nego"},
231 {98, 224, "allow.acc_nego"},
232 {98, 225, "allow.address_nego"},
233 {98, 226, "allow.vjcomp_nego"},
234 {98, 227, "allow.dns1_nego"},
235 {98, 228, "allow.dns2_nego"},
236 {77, 236, "allow.mru"},
237 {67, 240, "allow.accm"},
238 {65, 244, "allow.auth"},
239 {112, 248, "allow.ip_address"},
240 {112, 252, "allow.ip_mask"},
241 {112, 256, "allow.dns1"},
242 {112, 260, "allow.dns2"},
243 {76, 296, "log_flags"},
244 {99, 300, "force_chap_type"},
245 {98, 301, "omit_empty_frame"},
246 {80, 332, "phy_config"},
247 {98, 302, "pppoe"},
248 {98, 303, "pppoe_host_uniq_auto"},
249 {112, 308, "pppoe_service_name"},
250 {112, 312, "pppoe_ac_name"},
251 {52, 316, "mtu"},
252 {49, 324, "auth_timeout"},
253 {49, 321, "lcp_max_terminate"},
254 {49, 323, "ipcp_max_terminate"},
255 {49, 320, "lcp_max_configure"},
256 {49, 322, "ipcp_max_configure"},
257 {49, 325, "auth_max_failure"},
258 {0, 0, NULL}};
259static const struct netcnf_option g_options_dial_cnf[] = {
260 {112, 12, "chat_init"}, {112, 16, "chat_dial"}, {112, 20, "chat_answer"}, {112, 24, "redial_string"}, {0, 0, NULL}};
261static int g_callbacks_set;
262#ifdef _IOP
263// Unofficial: move to bss
264static void *g_netcnf_heap;
265static int g_semid;
266#endif
267static char g_icon_value[0x100];
268static char g_iconsys_value[0x100];
269static char g_id_xorbuf[24];
270static char g_id_buffer[8];
271static char g_ifc_buffer[0x3e8];
272static char g_arg_fname[0x400];
273static char g_entry_buffer[0x400];
274static char g_netcnf_file_path[0x100];
275static char g_dir_name[0x100];
276static char g_combination_buf1[0x100];
277static char g_combination_buf2[0x100];
278static char *g_read_check_netcnf_heapptr;
279static sceNetCnfCallback_t g_callbacks;
280static struct netcnf_callback_handle_info g_callback_handle_infos[4];
281static int g_open_callback_handle_count;
282
283static int get_check_provider_eq_zero(void)
284{
285 return !g_no_check_provider;
286}
287
288#ifdef _IOP
289static void do_print_usage(void)
290{
291 printf("Usage: netcnf [<option>] icon=<icon-path> iconsys=<iconsys-path>\n");
292 printf(" <option>:\n");
293 printf(" -no_check_capacity do not check capacity\n");
294 printf(" -no_check_provider do not check special provider\n");
295}
296
297static int do_module_load(int ac, char *av[], void *startaddr, ModuleInfo_t *mi)
298{
299 int semid;
300 int i;
301 iop_sema_t semaparam;
302 int err;
303
304 (void)startaddr;
305 if ( ac < 3 )
306 {
307 do_print_usage();
308 return MODULE_NO_RESIDENT_END;
309 }
310 err = 0;
311 semaparam.attr = SA_THPRI;
312 semaparam.initial = 1;
313 semaparam.max = 1;
314 semaparam.option = 0;
315 semid = CreateSema(&semaparam);
316 g_semid = semid;
317 if ( semid <= 0 )
318 {
319 printf("netcnf: CreateSema (%d)\n", semid);
320 return MODULE_NO_RESIDENT_END;
321 }
322 g_icon_value[0] = 0;
323 g_iconsys_value[0] = 0;
324 for ( i = 1; i < ac; i += 1 )
325 {
326 if ( !strncmp("icon=", av[i], 5) )
327 {
328 strcpy(g_icon_value, av[i] + 5);
329 }
330 else if ( !strncmp("iconsys=", av[i], 8) )
331 {
332 strcpy(g_iconsys_value, av[i] + 8);
333 }
334 else if ( !strcmp("-no_check_capacity", av[i]) )
335 {
336 g_no_check_capacity = 1;
337 }
338 else if ( !strcmp("-no_check_provider", av[i]) )
339 {
340 g_no_check_provider = 1;
341 }
342 else
343 {
344 err = 1;
345 break;
346 }
347 }
348 if ( !g_icon_value[0] || !g_iconsys_value[0] )
349 {
350 err = 1;
351 }
352 if ( !err )
353 {
354 int heap_inited;
355
356 heap_inited = do_init_heap();
357 if ( heap_inited < 0 )
358 {
359 printf("netcnf: init_heap(%d)\n", heap_inited);
360 }
361 else
362 {
363 int regres;
364
365 regres = RegisterLibraryEntries(&_exp_netcnf);
366 if ( !regres )
367 {
368#if 0
369 return MODULE_REMOVABLE_END;
370#else
371 if ( mi && ((mi->newflags & 2) != 0) )
372 mi->newflags |= 0x10;
373 return MODULE_RESIDENT_END;
374#endif
375 }
376 printf("netcnf: RegisterLibraryEntries(%d)\n", regres);
377 do_delete_heap();
378 }
379 }
380 if ( err == 1 )
381 {
382 do_print_usage();
383 }
384 DeleteSema(g_semid);
385 return MODULE_NO_RESIDENT_END;
386}
387
388static int do_module_unload(void)
389{
390 int relres;
391 int errstate;
392
393 errstate = 0;
394 relres = ReleaseLibraryEntries(&_exp_netcnf);
395 if ( relres )
396 {
397 printf("netcnf: ReleaseLibraryEntries (%d)\n", relres);
398 }
399 else
400 {
401 errstate = 1;
402 relres = DeleteSema(g_semid);
403 if ( relres )
404 {
405 printf("netcnf: DeleteSema (%d)\n", relres);
406 }
407 else
408 {
409 errstate = 2;
410 }
411 }
412 if ( errstate == 2 )
413 {
414 do_delete_heap();
415 return MODULE_NO_RESIDENT_END;
416 }
417 if ( errstate == 1 )
418 {
419 RegisterLibraryEntries(&_exp_netcnf);
420 }
421 return MODULE_REMOVABLE_END;
422}
423
424int _start(int ac, char *av[], void *startaddr, ModuleInfo_t *mi)
425{
426 return (ac >= 0) ? do_module_load(ac, av, startaddr, mi) : do_module_unload();
427}
428#endif
429
430int sceNetCnfGetCount(const char *fname, int type)
431{
432 int retres;
433
434#ifdef _IOP
435 WaitSema(g_semid);
436#endif
437 retres = do_get_count_list_inner(fname, type, 0);
438#ifdef _IOP
439 SignalSema(g_semid);
440#endif
441 return retres;
442}
443
444int sceNetCnfGetList(const char *fname, int type, sceNetCnfList_t *p)
445{
446 int retres;
447
448#ifdef _IOP
449 WaitSema(g_semid);
450#endif
451 retres = do_get_count_list_inner(fname, type, p);
452#ifdef _IOP
453 SignalSema(g_semid);
454#endif
455 return retres;
456}
457
458int sceNetCnfLoadEntry(const char *fname, int type, const char *usr_name, sceNetCnfEnv_t *e)
459{
460 int retres;
461
462#ifdef _IOP
463 WaitSema(g_semid);
464#endif
465 retres = do_load_entry_inner(fname, type, usr_name, e);
466#ifdef _IOP
467 SignalSema(g_semid);
468#endif
469 return retres;
470}
471
472int sceNetCnfAddEntry(const char *fname, int type, const char *usr_name, sceNetCnfEnv_t *e)
473{
474 int retres;
475
476#ifdef _IOP
477 WaitSema(g_semid);
478#endif
479 retres = do_add_entry_inner(fname, type, usr_name, e, g_icon_value, g_iconsys_value, g_no_check_capacity);
480#ifdef _IOP
481 SignalSema(g_semid);
482#endif
483 return retres;
484}
485
486int sceNetCnfEditEntry(const char *fname, int type, const char *usr_name, const char *new_usr_name, sceNetCnfEnv_t *e)
487{
488 int retres;
489
490#ifdef _IOP
491 WaitSema(g_semid);
492#endif
493 retres =
494 do_edit_entry_inner(fname, type, usr_name, new_usr_name, e, g_icon_value, g_iconsys_value, g_no_check_capacity);
495#ifdef _IOP
496 SignalSema(g_semid);
497#endif
498 return retres;
499}
500
501int sceNetCnfDeleteEntry(const char *fname, int type, const char *usr_name)
502{
503 int retres;
504
505#ifdef _IOP
506 WaitSema(g_semid);
507#endif
508 retres = do_delete_entry_inner(fname, type, usr_name, g_icon_value, g_iconsys_value, g_no_check_capacity);
509#ifdef _IOP
510 SignalSema(g_semid);
511#endif
512 return retres;
513}
514
515int sceNetCnfSetLatestEntry(const char *fname, int type, const char *usr_name)
516{
517 int retres;
518
519#ifdef _IOP
520 WaitSema(g_semid);
521#endif
522 retres = do_set_latest_entry_inner(fname, type, usr_name);
523#ifdef _IOP
524 SignalSema(g_semid);
525#endif
526 return retres;
527}
528
529void *sceNetCnfAllocMem(sceNetCnfEnv_t *e, int size, int align)
530{
531 return do_alloc_mem_inner(e, (unsigned int)size, align);
532}
533
534int sceNetCnfInitIFC(sceNetCnfInterface_t *ifc)
535{
536 if ( ifc )
537 {
538 memset(ifc, 0, sizeof(sceNetCnfInterface_t));
539 do_init_ifc_inner(ifc);
540 }
541 return 0;
542}
543
544int sceNetCnfLoadConf(sceNetCnfEnv_t *e)
545{
546 return do_load_conf_inner(e);
547}
548
549int sceNetCnfLoadDial(sceNetCnfEnv_t *e, sceNetCnfPair_t *pair)
550{
551 return do_load_dial_inner(e, pair);
552}
553
554int sceNetCnfMergeConf(sceNetCnfEnv_t *e)
555{
556 return do_merge_conf_inner(e);
557}
558
559int sceNetCnfName2Address(sceNetCnfAddress_t *paddr, const char *buf)
560{
561 unsigned int paddr_tmp;
562
563 paddr_tmp = 0;
564 if ( buf && !do_name_2_address_inner(&paddr_tmp, buf) )
565 {
566 return -1;
567 }
568 memset(paddr, 0, sizeof(sceNetCnfAddress_t));
569 memcpy(paddr->data, &paddr_tmp, sizeof(paddr_tmp));
570 return 0;
571}
572
573int sceNetCnfAddress2String(char *buf, int len, const sceNetCnfAddress_t *paddr)
574{
575 unsigned int buflen;
576 char buf_tmp[24];
577 unsigned int srcintx;
578
579 if ( paddr->reserved )
580 {
581 return -1;
582 }
583 memcpy(&srcintx, paddr->data, sizeof(srcintx));
584 do_address_to_string_inner(buf_tmp, srcintx);
585 buflen = (u32)strlen(buf_tmp) + 1;
586 if ( (unsigned int)len < buflen )
587 {
588 return -1;
589 }
590 memcpy(buf, buf_tmp, buflen);
591 return 0;
592}
593
594int sceNetCnfDeleteAll(const char *dev)
595{
596 int retres;
597
598#ifdef _IOP
599 WaitSema(g_semid);
600#endif
601 retres = do_delete_all_inner(dev);
602#ifdef _IOP
603 SignalSema(g_semid);
604#endif
605 return retres;
606}
607
608int sceNetCnfCheckCapacity(const char *fname)
609{
610 int retres;
611
612#ifdef _IOP
613 WaitSema(g_semid);
614#endif
615 retres = do_check_capacity_inner(fname);
616#ifdef _IOP
617 SignalSema(g_semid);
618#endif
619 return retres;
620}
621
622int sceNetCnfConvA2S(char *sp_, char *dp_, int len)
623{
624 int retres;
625
626 retres = do_conv_a2s_inner(sp_, dp_, len);
627 if ( retres )
628 {
629 return retres;
630 }
631 if ( len < (int)(strlen(sp_) + 1) )
632 {
633 return -19;
634 }
635 strcpy(dp_, sp_);
636 return 0;
637}
638
639int sceNetCnfConvS2A(char *sp_, char *dp_, int len)
640{
641 int retres;
642
643 retres = do_conv_s2a_inner(sp_, dp_, len);
644 if ( retres )
645 {
646 return retres;
647 }
648 if ( len < (int)(strlen(sp_) + 1) )
649 {
650 return -19;
651 }
652 strcpy(dp_, sp_);
653 return 0;
654}
655
656int sceNetCnfCheckSpecialProvider(const char *fname, int type, const char *usr_name, sceNetCnfEnv_t *e)
657{
658 int retres;
659
660#ifdef _IOP
661 WaitSema(g_semid);
662#endif
663 retres = do_check_special_provider_inner(fname, type, usr_name, e);
664#ifdef _IOP
665 SignalSema(g_semid);
666#endif
667 return retres;
668}
669
670void sceNetCnfSetCallback(sceNetCnfCallback_t *pcallback)
671{
672#ifdef _IOP
673 WaitSema(g_semid);
674#endif
675 do_set_callback_inner(pcallback);
676#ifdef _IOP
677 SignalSema(g_semid);
678#endif
679}
680
681static int do_read_ilink_id(void)
682{
683#ifdef _IOP
684 int i;
685
686 for ( i = 0; i < 20; i += 1 )
687 {
688 g_id_result = 0;
689 if ( sceCdRI((u8 *)g_id_buffer, &g_id_result) == 1 )
690 {
691 if ( !g_id_result )
692 return 0;
693 }
694 DelayThread(100000);
695 }
696 return -13;
697#else
698 memset(&g_id_buffer, 0, sizeof(g_id_buffer));
699 g_id_result = 0;
700 return 0;
701#endif
702}
703
704static int do_read_netcnf_decode(const char *netcnf_path, char **netcnf_heap_ptr)
705{
706 int result;
707 int fd;
708 int netcnf_size;
709 char *heapmem;
710 int xorind1;
711 int readres;
712 int i;
713
714 *netcnf_heap_ptr = 0;
715 result = do_read_ilink_id();
716 // cppcheck-suppress knownConditionTrueFalse
717 if ( result < 0 )
718 return result;
719 do_init_xor_magic(g_id_buffer);
720 fd = do_open_netcnf(netcnf_path, 1, 0);
721 if ( fd < 0 )
722 {
723 return (fd == -EIO) ? -18 : -3;
724 }
725 netcnf_size = do_filesize_netcnf(fd);
726 if ( netcnf_size < 0 )
727 {
728 do_close_netcnf(fd);
729 return netcnf_size;
730 }
731 heapmem = (char *)do_alloc_heapmem(netcnf_size + 1);
732 *netcnf_heap_ptr = heapmem;
733 if ( !heapmem )
734 {
735 do_close_netcnf(fd);
736 return -2;
737 }
738 xorind1 = 0;
739 readres = 0;
740 for ( i = 0; i < netcnf_size; i += 2 )
741 {
742 readres = do_readfile_netcnf(fd, &heapmem[i], 2);
743 if ( readres < 0 )
744 break;
745 *((u16 *)&heapmem[i]) ^= 0xFFFF;
746 *((u16 *)&heapmem[i]) = (u16)magic_shift_read_netcnf_1(*((u16 *)&heapmem[i]), (u8)g_id_xorbuf[xorind1 + 2]);
747 xorind1 += 1;
748 xorind1 = (xorind1 != sizeof(g_id_xorbuf)) ? xorind1 : 0;
749 }
750 if ( readres >= 0 )
751 {
752 if ( (netcnf_size & 1) != 0 )
753 {
754 readres = do_readfile_netcnf(fd, &heapmem[netcnf_size - 1], 1);
755 if ( readres >= 0 )
756 {
757 heapmem[netcnf_size - 1] ^= 0xFF;
758 heapmem[netcnf_size - 1] =
759 (char)magic_shift_read_netcnf_2(heapmem[netcnf_size - 1], (u8)g_id_xorbuf[xorind1 + 2]);
760 }
761 }
762 if ( readres >= 0 )
763 {
764 heapmem[netcnf_size] = 0;
765 do_close_netcnf(fd);
766 return netcnf_size;
767 }
768 }
769 do_free_heapmem(heapmem);
770 *netcnf_heap_ptr = 0;
771 do_close_netcnf(fd);
772 return (readres != -EIO) ? -4 : -18;
773}
774
775static int do_write_netcnf_encode(const char *netcnf_path, void *buf, int netcnf_len)
776{
777 int result;
778 int fd;
779 u16 *buf_1;
780 int netcnf_len_1;
781 int xorind1;
782 int xoroffs;
783 int writeres;
784 u16 bufflipx1;
785 char bufflipx2;
786
787 result = do_read_ilink_id();
788 // cppcheck-suppress knownConditionTrueFalse
789 if ( result < 0 )
790 return result;
791 do_init_xor_magic(g_id_buffer);
792 fd = do_open_netcnf(netcnf_path, 1538, 511);
793 buf_1 = (u16 *)buf;
794 if ( fd < 0 )
795 {
796 return (fd == -EIO) ? -18 : -3;
797 }
798 netcnf_len_1 = netcnf_len;
799 xorind1 = 0;
800 xoroffs = 0;
801 writeres = 0;
802 while ( writeres >= 0 )
803 {
804 while ( netcnf_len_1 >= 2 )
805 {
806 bufflipx1 = (u16)magic_shift_write_netcnf_1(*buf_1, (u8)g_id_xorbuf[xorind1 + 2]);
807 xorind1 += 1;
808 xorind1 = (xorind1 != sizeof(g_id_xorbuf)) ? xorind1 : 0;
809 bufflipx1 ^= 0xFFFF;
810 writeres = do_write_netcnf_no_encode(fd, &bufflipx1, sizeof(bufflipx1));
811 buf_1 += 1;
812 if ( writeres < 0 )
813 break;
814 netcnf_len_1 -= 2;
815 xoroffs += 2;
816 }
817 if ( writeres >= 0 && !netcnf_len_1 )
818 {
819 do_close_netcnf(fd);
820 return xoroffs;
821 }
822 if ( writeres >= 0 )
823 {
824 bufflipx2 = (char)magic_shift_write_netcnf_2(*(u8 *)buf_1, (u8)g_id_xorbuf[xorind1 + 2]);
825 xorind1 += 1;
826 xorind1 = (xorind1 != sizeof(g_id_xorbuf)) ? xorind1 : 0;
827 bufflipx2 ^= 0xFF;
828 writeres = do_write_netcnf_no_encode(fd, &bufflipx2, sizeof(bufflipx2));
829 netcnf_len_1 -= 1;
830 xoroffs += 1;
831 }
832 }
833 do_close_netcnf(fd);
834 return (writeres != -EIO) ? -5 : -18;
835}
836
837static int do_read_netcnf_no_decode(const char *netcnf_path, char **netcnf_heap_ptr)
838{
839 int fd;
840 int netcnf_size;
841 char *netcnf_data;
842
843 *netcnf_heap_ptr = 0;
844 fd = do_open_netcnf(netcnf_path, 1, 0);
845 if ( fd < 0 )
846 {
847 return (fd != -EIO) ? -3 : -18;
848 }
849 netcnf_size = do_filesize_netcnf(fd);
850 if ( netcnf_size < 0 )
851 {
852 do_close_netcnf(fd);
853 return netcnf_size;
854 }
855 netcnf_data = (char *)do_alloc_heapmem(netcnf_size + 1);
856 *netcnf_heap_ptr = netcnf_data;
857 if ( !netcnf_data )
858 {
859 do_close_netcnf(fd);
860 return -2;
861 }
862 netcnf_size = do_readfile_netcnf(fd, netcnf_data, netcnf_size);
863 if ( netcnf_size < 0 )
864 {
865 do_free_heapmem(*netcnf_heap_ptr);
866 *netcnf_heap_ptr = 0;
867 do_close_netcnf(fd);
868 return (netcnf_size != -EIO) ? -4 : -18;
869 }
870 netcnf_data[netcnf_size] = 0;
871 do_close_netcnf(fd);
872 return netcnf_size;
873}
874
875static void do_init_xor_magic(const char *in_id_buf)
876{
877 int i;
878
879 for ( i = 0; (i + 1) < 8; i += 1 )
880 {
881 g_id_xorbuf[(i * 3) + 2] = ((u8)in_id_buf[i] >> 5) + 1;
882 g_id_xorbuf[(i * 3) + 3] = (((u8)in_id_buf[i] >> 2) & 7) + 1;
883 g_id_xorbuf[(i * 3) + 4] = (in_id_buf[i] & 3) + 1;
884 }
885}
886
887static int magic_shift_write_netcnf_2(int inshft, int buflen)
888{
889 for ( ; buflen; buflen -= 1 )
890 inshft = ((u8)inshft >> 7) | (inshft << 1);
891 return (u8)inshft;
892}
893
894static int magic_shift_read_netcnf_2(int inshft, int buflen)
895{
896 for ( ; buflen; buflen -= 1 )
897 inshft = ((u8)inshft >> 1) | (inshft << 7);
898 return (u8)inshft;
899}
900
901static int magic_shift_write_netcnf_1(int inshft, int buflen)
902{
903 for ( ; buflen; buflen -= 1 )
904 inshft = ((u16)inshft >> 15) | (inshft << 1);
905 return (u16)inshft;
906}
907
908static int magic_shift_read_netcnf_1(int inshft, int buflen)
909{
910 for ( ; buflen; buflen -= 1 )
911 inshft = ((u16)inshft >> 1) | (inshft << 15);
912 return (u16)inshft;
913}
914
915static void do_safe_strcpy(char *dst, size_t maxlen, const char *src, int linenum)
916{
917 if ( strlen(src) >= maxlen )
918 {
919 printf("[netcnf] strcpy failed(%d)\n", linenum);
920 return;
921 }
922 strcpy(dst, src);
923}
924
925static void do_safe_strcat(char *dst, size_t maxlen, const char *src, int linenum)
926{
927 if ( strlen(dst) + strlen(src) >= maxlen )
928 {
929 printf("[netcnf] strcat failed(%d)\n", linenum);
930 return;
931 }
932 strcat(dst, src);
933}
934
935static void do_safe_make_pathname(char *dst, size_t maxlen, const char *srcdir, const char *srcbase)
936{
937 if ( strlen(srcdir) + strlen(srcbase) + 1 >= maxlen )
938 {
939 printf("[netcnf] make_pathname failed\n");
940 return;
941 }
942 strcpy(dst, srcdir);
943 strcat(dst, "/");
944 strcat(dst, srcbase);
945}
946
947static void do_safe_make_name(char *dst, size_t maxlen, const char *src1, const char *src2)
948{
949 if ( strlen(src1) + strlen(src2) >= maxlen )
950 {
951 printf("[netcnf] make_name failed\n");
952 return;
953 }
954 strcpy(dst, src1);
955 strcat(dst, src2);
956}
957
958static int do_check_capacity_inner2(const char *fpath, int minsize)
959{
960 int i;
961 int zonefree;
962 char devname[8];
963
964 for ( i = 0; i < 5; i += 1 )
965 {
966 devname[i] = fpath[i];
967 if ( fpath[i] == ':' )
968 {
969 devname[i + 1] = 0;
970#ifdef _IOP
971 zonefree = iomanX_devctl(devname, 0x5002, 0, 0, 0, 0) * ((int)iomanX_devctl(devname, 0x5001, 0, 0, 0, 0) / 1024);
972#else
973 {
974 struct statvfs st;
975
976 statvfs(devname, &st);
977 zonefree = (int)(u32)(st.f_bfree * st.f_frsize);
978 }
979#endif
980 return (zonefree < minsize) ? -16 : 0;
981 }
982 }
983 return -9;
984}
985
986static int do_check_capacity_inner(const char *fpath)
987{
988 int minsize;
989
990 if ( !strncmp(fpath, "mc", 2) )
991 minsize = 0x5E;
992 else if ( !strncmp(fpath, "pfs", 3) )
993 minsize = 0xF4;
994 else
995 return -9;
996 return do_check_capacity_inner2(fpath, minsize);
997}
998
999static int do_handle_combination_path(int type, const char *fpath, char *dst, size_t maxlen, const char *usr_name)
1000{
1001 char *i;
1002 int j;
1003 int devnr;
1004 char devnum[8];
1005
1006 if ( !usr_name )
1007 return -11;
1008 do_safe_strcpy(dst, maxlen, usr_name, 139);
1009 if ( type )
1010 return 0;
1011 for ( i = dst; !isdigit(*i); i += 1 )
1012 ;
1013 for ( j = 0; j < 4 && isdigit(i[j]); j += 1 )
1014 {
1015 devnum[j] = i[j];
1016 }
1017 if ( j >= 4 )
1018 return -11;
1019 devnum[j] = 0;
1020 devnr = (int)strtol(devnum, 0, 10);
1021 if (
1022 !strncmp(fpath, "mc", 2) ? ((unsigned int)(devnr - 1) >= 6) :
1023 (!strncmp(fpath, "pfs", 3) ? (unsigned int)(devnr - 1) >= 0xA :
1024 (unsigned int)(devnr - 1) >= sizeof(g_ifc_buffer)) )
1025 return -11;
1026 do_safe_make_name(dst, maxlen, "Combination", devnum);
1027 return 0;
1028}
1029
1030static int do_copy_netcnf_path(const char *netcnf_path_1, const char *netcnf_path_2)
1031{
1032 int fd2;
1033 int fd1;
1034 int readres;
1035 char tmpbuf[512];
1036
1037 fd2 = do_open_netcnf(netcnf_path_2, 1538, 511);
1038 if ( fd2 < 0 )
1039 return -3;
1040 fd1 = do_open_netcnf(netcnf_path_1, 1, 0);
1041 if ( fd1 < 0 )
1042 {
1043 do_close_netcnf(fd2);
1044 return -3;
1045 }
1046 while ( 1 )
1047 {
1048 int writeres;
1049
1050 readres = do_readfile_netcnf(fd1, tmpbuf, sizeof(tmpbuf));
1051 if ( readres <= 0 )
1052 break;
1053 writeres = do_write_netcnf_no_encode(fd2, tmpbuf, readres);
1054 if ( readres != writeres )
1055 {
1056 do_close_netcnf(fd2);
1057 do_close_netcnf(fd1);
1058 return -5;
1059 }
1060 }
1061 do_close_netcnf(fd2);
1062 do_close_netcnf(fd1);
1063 return (readres < 0) ? -4 : 0;
1064}
1065
1066static char *do_write_memcard_pathcopy(char *dst, size_t maxlen, const char *src)
1067{
1068 char *dst_end_slash;
1069
1070 do_safe_strcpy(dst, maxlen, src, 218);
1071 for ( dst_end_slash = &dst[strlen(dst)]; *dst_end_slash != '/'; dst_end_slash -= 1 )
1072 ;
1073 for ( ; *dst_end_slash == '/'; dst_end_slash -= 1 )
1074 ;
1075 if ( *dst_end_slash == ':' )
1076 return 0;
1077 dst_end_slash[1] = 0;
1078 return dst;
1079}
1080
1081static int do_write_memcard_files(const char *fpath, const char *icon_value, const char *iconsys_value)
1082{
1083 int result;
1084 char cur_basepath[256];
1085 char cur_combpath[256];
1086
1087 if ( !do_write_memcard_pathcopy(cur_basepath, sizeof(cur_basepath), fpath) )
1088 return 0;
1089 do_safe_make_pathname(cur_combpath, sizeof(cur_combpath), cur_basepath, "SYS_NET.ICO");
1090 result = do_copy_netcnf_path(icon_value, cur_combpath);
1091 if ( result < 0 )
1092 return result;
1093 do_safe_make_pathname(cur_combpath, sizeof(cur_combpath), cur_basepath, "icon.sys");
1094 result = do_copy_netcnf_path(iconsys_value, cur_combpath);
1095 if ( result < 0 )
1096 return result;
1097 return 0;
1098}
1099
1100static int do_handle_fname(char *fpath, size_t maxlen, const char *fname)
1101{
1102 char *index_res;
1103 const char *pathname;
1104 int maxbuf;
1105
1106 do_safe_strcpy(fpath, maxlen, fname, 266);
1107 index_res = index(fpath, ':');
1108 if ( !index_res )
1109 return -9;
1110 if ( !strncmp(fpath, "mc", 2) )
1111 {
1112 index_res[1] = 0;
1113 pathname = "/BWNETCNF/BWNETCNF";
1114 maxbuf = 275;
1115 }
1116 else if ( !strncmp(fpath, "pfs", 3) )
1117 {
1118 index_res[1] = 0;
1119 pathname = "/etc/network/net.db";
1120 maxbuf = 279;
1121 }
1122 else
1123 return 0;
1124 do_safe_strcat(fpath, maxlen, pathname, maxbuf);
1125 return 0;
1126}
1127
1128static const char *do_get_str_line(const char *buf)
1129{
1130 for ( ; *buf && *buf != '\n'; buf += 1 )
1131 ;
1132 return &buf[*buf == '\n'];
1133}
1134
1135static int do_split_str_comma_index(char *dst, const char *src, int commaind)
1136{
1137 int i;
1138
1139 for ( i = 0; i < commaind; i += 1 )
1140 {
1141 for ( ; *src && *src != '\n' && *src != ','; src += 1 )
1142 ;
1143 if ( *src != ',' )
1144 return -1;
1145 src += 1;
1146 }
1147 for ( ; *src && *src != ',' && *src != '\n' && *src != '\r'; src += 1 )
1148 {
1149 *dst = *src;
1150 dst += 1;
1151 }
1152 *dst = 0;
1153 return 0;
1154}
1155
1156static int
1157do_remove_old_config(const char *fpath, const char *netcnf_heap_buf, const char *icon_value, const char *iconsys_value)
1158{
1159 int sysneticoflag;
1160 int dfd;
1161 int fileop_res;
1162 const char *curheapbuf1;
1163 char cur_basepath[256];
1164 char cur_combpath[256];
1165 iox_dirent_t statname;
1166 iox_stat_t statsize;
1167 int iconsysflag;
1168
1169 sysneticoflag = 1;
1170 iconsysflag = 1;
1171 if ( !do_write_memcard_pathcopy(cur_basepath, sizeof(cur_basepath), fpath) )
1172 return 0;
1173 dfd = do_dopen_wrap(cur_basepath);
1174 // cppcheck-suppress knownConditionTrueFalse
1175 if ( dfd < 0 )
1176 {
1177 return (dfd == -EIO) ? -18 : 0;
1178 }
1179 while ( 1 )
1180 {
1181 int sizeflag;
1182
1183 fileop_res = do_dread_wrap(dfd, &statname);
1184 // cppcheck-suppress knownConditionTrueFalse
1185 if ( fileop_res <= 0 )
1186 break;
1187 sizeflag = 1;
1188 if ( strlen(statname.name) == 10 )
1189 {
1190 if ( !strncmp(&statname.name[6], ".cnf", 4) || !strncmp(&statname.name[6], ".dat", 4) )
1191 {
1192 for ( curheapbuf1 = netcnf_heap_buf; curheapbuf1 && *curheapbuf1; curheapbuf1 = do_get_str_line(curheapbuf1) )
1193 {
1194 do_split_str_comma_index(cur_combpath, curheapbuf1, 2);
1195 if ( !strcmp(statname.name, cur_combpath) )
1196 {
1197 do_safe_make_pathname(cur_combpath, sizeof(cur_combpath), cur_basepath, statname.name);
1198 sizeflag = 0;
1199 break;
1200 }
1201 }
1202 }
1203 }
1204 else if ( !strncmp(fpath, "mc", 2) )
1205 {
1206 if ( !strcmp(statname.name, "SYS_NET.ICO") )
1207 {
1208 do_safe_make_pathname(cur_combpath, sizeof(cur_combpath), cur_basepath, statname.name);
1209 do_getstat_wrap(cur_combpath, &statsize);
1210 if ( statsize.size != 0x8398 )
1211 {
1212 sizeflag = 0;
1213 }
1214 else
1215 {
1216 sysneticoflag = 0;
1217 }
1218 }
1219 else if ( !strcmp(statname.name, "icon.sys") )
1220 {
1221 do_safe_make_pathname(cur_combpath, sizeof(cur_combpath), cur_basepath, statname.name);
1222 do_getstat_wrap(cur_combpath, &statsize);
1223 if ( statsize.size != 0x3C4 )
1224 {
1225 sizeflag = 0;
1226 }
1227 else
1228 {
1229 iconsysflag = 0;
1230 }
1231 }
1232 else if ( strcmp(statname.name, "BWNETCNF") )
1233 {
1234 do_safe_make_pathname(cur_combpath, sizeof(cur_combpath), cur_basepath, statname.name);
1235 sizeflag = 0;
1236 }
1237 }
1238 else if ( !strncmp(fpath, "pfs", 3) && strcmp(statname.name, "net.db") )
1239 {
1240 do_safe_make_pathname(cur_combpath, sizeof(cur_combpath), cur_basepath, statname.name);
1241 sizeflag = 0;
1242 }
1243 if ( !sizeflag )
1244 {
1245 fileop_res = do_remove_wrap(cur_combpath);
1246 if ( fileop_res == -EIO )
1247 break;
1248 }
1249 }
1250 if ( fileop_res == -EIO )
1251 {
1252 do_dclose_wrap(dfd);
1253 return -18;
1254 }
1255 do_dclose_wrap(dfd);
1256 if ( !strncmp(fpath, "mc", 2) )
1257 {
1258 if ( sysneticoflag || iconsysflag )
1259 fileop_res = do_write_memcard_files(fpath, icon_value, iconsys_value);
1260 do_chstat_mode_copyprotect_wrap(cur_basepath);
1261 }
1262 return fileop_res;
1263}
1264
1265static int do_type_check(int type, const char *buf)
1266{
1267 return (do_split_str_comma_index(g_arg_fname, buf, 0)) ? -1 : (strtol(g_arg_fname, 0, 10) == type);
1268}
1269
1270static int do_read_current_netcnf_nodecode(const char *fpath, char **netcnf_heap_ptr)
1271{
1272 int retres;
1273
1274 if ( !fpath )
1275 return -9;
1276 retres = do_read_netcnf_no_decode(fpath, netcnf_heap_ptr);
1277 return (retres < 0) ? ((retres != -3) ? retres : 0) : retres;
1278}
1279
1280static int do_write_noencode_netcnf_atomic(const char *fpath, void *ptr, int size)
1281{
1282 int fd;
1283 int writeres;
1284 char fpath_comb[256];
1285
1286 if ( !fpath )
1287 return -9;
1288 do_safe_make_name(fpath_comb, sizeof(fpath_comb), fpath, ".tmp");
1289 fd = do_open_netcnf(fpath_comb, 1538, 511);
1290 if ( fd < 0 )
1291 {
1292 return (fd == -EIO) ? -18 : -3;
1293 }
1294 writeres = do_write_netcnf_no_encode(fd, ptr, size);
1295 do_close_netcnf(fd);
1296 // Unofficial: dead code removed
1297 return (size != writeres) ? ((writeres != -EIO) ? -5 : -18) : ((iomanX_rename(fpath_comb, fpath) == -EIO) ? -18 : 0);
1298}
1299
1300static int do_remove_netcnf_dirname(const char *dirpath, const char *entry_buffer)
1301{
1302 const char *p_dirname;
1303 int remove_res_1;
1304
1305 p_dirname = do_handle_netcnf_dirname(dirpath, entry_buffer, g_netcnf_file_path);
1306 if ( !p_dirname )
1307 return -7;
1308 remove_res_1 = do_remove_wrap(p_dirname);
1309 return (remove_res_1 < 0) ? ((remove_res_1 == -EIO) ? -18 : -7) : 0;
1310}
1311
1312static int do_get_count_list_inner(const char *fname, int type, sceNetCnfList_t *p)
1313{
1314 int result;
1315 const char *curheapbuf1;
1316 int curind1;
1317
1318 result = do_handle_fname(g_dir_name, sizeof(g_dir_name), fname);
1319 if ( result < 0 )
1320 return result;
1321 result = do_read_current_netcnf_nodecode(g_dir_name, &g_count_list_heapptr);
1322 if ( result <= 0 )
1323 return result;
1324 curind1 = 0;
1325 for ( curheapbuf1 = g_count_list_heapptr; *curheapbuf1; curheapbuf1 = do_get_str_line(curheapbuf1) )
1326 {
1327 if ( do_type_check(type, curheapbuf1) <= 0 )
1328 continue;
1329 curind1 += 1;
1330 if ( !p )
1331 continue;
1332 p->type = type;
1333 if ( do_split_str_comma_index(g_arg_fname, curheapbuf1, 1) )
1334 continue;
1335 p->stat = (int)strtol(g_arg_fname, 0, 10);
1336 if (
1337 do_split_str_comma_index(p->sys_name, curheapbuf1, 2) || do_split_str_comma_index(p->usr_name, curheapbuf1, 3) )
1338 continue;
1339 p += 1;
1340 }
1341 do_free_heapmem(g_count_list_heapptr);
1342 return curind1;
1343}
1344
1345static int do_load_entry_inner(const char *fname, int type, const char *usr_name, sceNetCnfEnv_t *e)
1346{
1347 int result;
1348 const char *curheapbuf1;
1349
1350 result = do_handle_fname(g_dir_name, sizeof(g_dir_name), fname);
1351 if ( result < 0 )
1352 return result;
1353 result = do_handle_combination_path(type, g_dir_name, g_combination_buf1, sizeof(g_combination_buf1), usr_name);
1354 if ( result < 0 )
1355 return result;
1356 result = do_read_current_netcnf_nodecode(g_dir_name, &g_load_entry_heapptr);
1357 if ( result <= 0 )
1358 return !result ? -8 : result;
1359 for ( curheapbuf1 = g_load_entry_heapptr; *curheapbuf1; curheapbuf1 = do_get_str_line(curheapbuf1) )
1360 {
1361 if (
1362 do_type_check(type, curheapbuf1) >= 0 && !do_split_str_comma_index(g_arg_fname, curheapbuf1, 3)
1363 && !strcmp(g_arg_fname, g_combination_buf1) && !do_split_str_comma_index(g_arg_fname, curheapbuf1, 2) )
1364 {
1365 do_free_heapmem(g_load_entry_heapptr);
1366 e->dir_name = g_dir_name;
1367 e->arg_fname = g_arg_fname;
1368 e->req = type ? 2 : 1;
1369 return do_load_conf_inner(e);
1370 }
1371 }
1372 do_free_heapmem(g_load_entry_heapptr);
1373 return -8;
1374}
1375
1376static void do_extra_ifc_handling(const char *arg_fname)
1377{
1378 const char *i;
1379 const char *curptr1;
1380 unsigned int curbufsz1;
1381 unsigned int curindx;
1382
1383 if ( !arg_fname || !*arg_fname )
1384 return;
1385 for ( i = &arg_fname[strlen(arg_fname) - 1]; i >= arg_fname && *i != '.'; i -= 1 )
1386 ;
1387 curptr1 = i - 1;
1388 if ( curptr1 < arg_fname || *i != '.' || !isdigit(*curptr1) )
1389 return;
1390 curbufsz1 = 0;
1391 curindx = 1;
1392 for ( ; curptr1 >= arg_fname && isdigit(*curptr1); curptr1 -= 1 )
1393 {
1394 curbufsz1 += curindx * (u8)(*curptr1 - '0');
1395 curindx *= 10;
1396 }
1397 if ( curbufsz1 < sizeof(g_ifc_buffer) )
1398 g_ifc_buffer[curbufsz1] = 1;
1399}
1400
1401static void do_extra_pair_handling(char *fpath, int type, const char *src, const sceNetCnfEnv_t *e)
1402{
1403 sceNetCnfEnv_t *heapmem;
1404 int conf_inner;
1405 struct sceNetCnfPair *i;
1406
1407 if ( do_split_str_comma_index(g_arg_fname, src, 2) )
1408 return;
1409 heapmem = (sceNetCnfEnv_t *)do_alloc_heapmem(sizeof(sceNetCnfEnv_t) + 4096);
1410 if ( !heapmem )
1411 return;
1412 heapmem->req = 1;
1413 heapmem->mem_ptr = &heapmem[1];
1414 heapmem->mem_base = &heapmem[1];
1415 heapmem->dir_name = fpath;
1416 heapmem->arg_fname = g_arg_fname;
1417 heapmem->mem_last = ((char *)&heapmem[1]) + 4096;
1418 heapmem->f_no_check_magic = e->f_no_check_magic;
1419 heapmem->f_no_decode = e->f_no_decode;
1420 heapmem->f_verbose = e->f_verbose;
1421 conf_inner = do_load_conf_inner(heapmem);
1422 if ( (!conf_inner || conf_inner == -21) && heapmem->root )
1423 {
1424 for ( i = heapmem->root->pair_head; i; i = i->forw )
1425 {
1426 switch ( type )
1427 {
1428 case 1:
1429 do_extra_ifc_handling((char *)i->attach_ifc);
1430 break;
1431 case 2:
1432 do_extra_ifc_handling((char *)i->attach_dev);
1433 break;
1434 default:
1435 continue;
1436 }
1437 }
1438 }
1439 do_free_heapmem(heapmem);
1440}
1441
1442static int do_add_entry_inner(
1443 const char *fname,
1444 int type,
1445 const char *usr_name,
1446 sceNetCnfEnv_t *e,
1447 const char *icon_value,
1448 const char *iconsys_value,
1449 int no_check_capacity)
1450{
1451 int result;
1452 int retres2;
1453 const char *curentry1;
1454 int i;
1455 const char *curentry2;
1456 const char *k;
1457 int fd;
1458 char atomicrenamepath[256];
1459 int retres1;
1460 int maxflag;
1461
1462 maxflag = 1;
1463 fd = -EPERM;
1464 if ( get_check_provider_eq_zero() )
1465 {
1466 result = do_check_provider_inner(e, type);
1467 if ( result < 0 )
1468 return result;
1469 }
1470 result = do_handle_fname(g_dir_name, sizeof(g_dir_name), fname);
1471 if ( result < 0 )
1472 return result;
1473 if ( !no_check_capacity )
1474 {
1475 result = do_check_capacity_inner(g_dir_name);
1476 if ( result < 0 )
1477 return result;
1478 }
1479 atomicrenamepath[0] = 0;
1480 result = do_handle_combination_path(type, g_dir_name, g_combination_buf1, sizeof(g_combination_buf1), usr_name);
1481 if ( result < 0 )
1482 return result;
1483 retres1 = do_read_current_netcnf_nodecode(g_dir_name, &g_add_entry_heapptr);
1484 if ( retres1 < 0 )
1485 return result;
1486 retres2 = do_remove_old_config(g_dir_name, g_add_entry_heapptr, icon_value, iconsys_value);
1487 if ( retres2 < 0 )
1488 maxflag = 0;
1489 if ( maxflag )
1490 {
1491 memset(g_ifc_buffer, 0, sizeof(g_ifc_buffer));
1492 if ( retres1 )
1493 {
1494 if ( !strncmp(g_dir_name, "mc", 2) )
1495 {
1496 i = 0;
1497 for ( curentry1 = g_add_entry_heapptr; *curentry1; curentry1 = do_get_str_line(curentry1) )
1498 {
1499 if ( do_type_check(type, curentry1) == 1 )
1500 i += 1;
1501 }
1502 switch ( type )
1503 {
1504 case 0:
1505 retres2 = -12;
1506 if ( i >= 6 )
1507 maxflag = 0;
1508 break;
1509 case 1:
1510 case 2:
1511 retres2 = -12;
1512 if ( i >= 4 )
1513 maxflag = 0;
1514 break;
1515 default:
1516 break;
1517 }
1518 }
1519 else if ( !strncmp(g_dir_name, "pfs", 3) )
1520 {
1521 i = 0;
1522 for ( curentry2 = g_add_entry_heapptr; *curentry2; curentry2 = do_get_str_line(curentry2) )
1523 {
1524 if ( do_type_check(type, curentry2) == 1 )
1525 i += 1;
1526 }
1527 switch ( type )
1528 {
1529 case 0:
1530 retres2 = -12;
1531 if ( i >= 10 )
1532 maxflag = 0;
1533 break;
1534 case 1:
1535 case 2:
1536 retres2 = -12;
1537 if ( i >= 30 )
1538 maxflag = 0;
1539 break;
1540 default:
1541 break;
1542 }
1543 }
1544 if ( maxflag )
1545 {
1546 for ( k = g_add_entry_heapptr; *k; k = do_get_str_line(k) )
1547 {
1548 if ( (unsigned int)(type - 1) < 2 && do_type_check(0, k) > 0 )
1549 do_extra_pair_handling(g_dir_name, type, k, e);
1550 if (
1551 do_type_check(type, k) > 0 && !do_split_str_comma_index(g_arg_fname, k, 1)
1552 && strtol(g_arg_fname, 0, 10) == 1 && !do_split_str_comma_index(g_arg_fname, k, 2) )
1553 {
1554 do_extra_ifc_handling(g_arg_fname);
1555 if ( !do_split_str_comma_index(g_arg_fname, k, 3) && !strcmp(g_combination_buf1, g_arg_fname) )
1556 {
1557 do_free_heapmem(g_add_entry_heapptr);
1558 return -11;
1559 }
1560 }
1561 }
1562 }
1563 }
1564 }
1565 if ( maxflag )
1566 {
1567 char *endbuf;
1568 const char *fileext;
1569
1570 do_safe_strcpy(g_arg_fname, sizeof(g_arg_fname), g_dir_name, 740);
1571 for ( endbuf = &g_arg_fname[strlen(g_arg_fname) - 1];
1572 endbuf >= g_arg_fname && *endbuf != ':' && *endbuf != '/' && *endbuf != '\\';
1573 endbuf -= 1 )
1574 ;
1575 if ( endbuf >= g_arg_fname && *endbuf != ':' && *endbuf != '/' && *endbuf != '\\' )
1576 {
1577 *endbuf = 0;
1578 }
1579 else
1580 {
1581 endbuf[1] = 0;
1582 }
1583 fileext = (type && !e->f_no_decode) ? ".dat" : ".cnf";
1584 for ( i = 0; i < (int)(sizeof(g_ifc_buffer)); i += 1 )
1585 {
1586 if ( !g_ifc_buffer[i] )
1587 {
1588 switch ( type )
1589 {
1590 case 1:
1591 // Unofficial: specify max length for g_arg_fname to avoid overflow
1592 sprintf(g_netcnf_file_path, "%.245sifc%03d%s", g_arg_fname, i, fileext);
1593 break;
1594 case 2:
1595 // Unofficial: specify max length for g_arg_fname to avoid overflow
1596 sprintf(g_netcnf_file_path, "%.245sdev%03d%s", g_arg_fname, i, fileext);
1597 break;
1598 case 3:
1599 // Unofficial: specify max length for g_arg_fname to avoid overflow
1600 sprintf(g_netcnf_file_path, "%.245snet%03d%s", g_arg_fname, i, fileext);
1601 break;
1602 default:
1603 do_free_heapmem(g_add_entry_heapptr);
1604 return -10;
1605 }
1606 fd = do_open_netcnf(g_netcnf_file_path, 1, 0);
1607 if ( fd < 0 )
1608 {
1609 if ( fd == -EIO )
1610 return -18;
1611 break;
1612 }
1613 do_close_netcnf(fd);
1614 }
1615 }
1616 retres2 = -12;
1617 if ( i < (int)(sizeof(g_ifc_buffer)) )
1618 {
1619 char *dirname_buf1;
1620 char *cur_entry_buffer;
1621
1622 cur_entry_buffer = g_entry_buffer;
1623 for ( dirname_buf1 = g_dir_name; *dirname_buf1; dirname_buf1 += 1 )
1624 {
1625 if ( (*dirname_buf1 == '/' || *dirname_buf1 == '\\') && dirname_buf1[1] )
1626 {
1627 *cur_entry_buffer = 0;
1628 retres2 = mkdir(g_entry_buffer, 511);
1629 if ( !retres2 && !strncmp(g_dir_name, "mc", 2) )
1630 {
1631 do_chstat_mode_copyprotect_wrap(g_entry_buffer);
1632 retres2 = do_write_memcard_files(g_dir_name, icon_value, iconsys_value);
1633 if ( retres2 < 0 )
1634 break;
1635 }
1636 if ( retres2 == -5 )
1637 break;
1638 retres2 = -18;
1639 }
1640 *cur_entry_buffer = *dirname_buf1;
1641 cur_entry_buffer += 1;
1642 }
1643 if ( *dirname_buf1 )
1644 {
1645 e->dir_name = g_dir_name;
1646 e->arg_fname = &g_netcnf_file_path[strlen(g_arg_fname)];
1647 e->req = type ? 2 : 1;
1648 retres2 = -1;
1649 if ( !do_export_netcnf(e) )
1650 {
1651 do_safe_make_name(atomicrenamepath, sizeof(atomicrenamepath), g_dir_name, ".tmp");
1652 fd = do_open_netcnf(atomicrenamepath, 1538, 511);
1653 if ( fd < 0 )
1654 {
1655 retres2 = (fd == -EIO) ? -18 : -3;
1656 }
1657 else
1658 {
1659 int strlenx;
1660 int writeres;
1661
1662 strlenx = sprintf(
1663 g_entry_buffer, "%d,%d,%s,%s\n", type, 1, &g_netcnf_file_path[strlen(g_arg_fname)], g_combination_buf1);
1664 writeres = do_write_netcnf_no_encode(fd, g_entry_buffer, strlenx);
1665 retres2 = 0;
1666 if ( strlenx != writeres )
1667 {
1668 retres2 = (writeres == -EIO) ? -18 : -5;
1669 }
1670 else
1671 {
1672 writeres = do_write_netcnf_no_encode(fd, g_add_entry_heapptr, retres1);
1673 if ( retres1 != writeres )
1674 {
1675 retres2 = (writeres == -EIO) ? -18 : -5;
1676 }
1677 }
1678 }
1679 }
1680 }
1681 }
1682 }
1683 do_free_heapmem(g_add_entry_heapptr);
1684 if ( fd >= 0 )
1685 do_close_netcnf(fd);
1686 // Unofficial: dead code removed
1687 return (atomicrenamepath[0] && iomanX_rename(atomicrenamepath, g_dir_name) == -EIO) ?
1688 -18 :
1689 ((strncmp(g_dir_name, "pfs", 3) || iomanX_sync(g_dir_name, 0) != -EIO) ? retres2 : -18);
1690}
1691
1692static int do_handle_set_usrname(const char *fpath, int type, const char *usrname_buf2, const char *usrname_bufnew)
1693{
1694 int result;
1695 int retres1;
1696 char *heapmem;
1697 const char *ptr_1;
1698 char *heapmem_1;
1699 int writeres1;
1700 char *ptr;
1701
1702 ptr = 0;
1703 if ( !usrname_buf2 )
1704 return -11;
1705 result = do_handle_combination_path(type, g_dir_name, g_combination_buf1, sizeof(g_combination_buf1), usrname_bufnew);
1706 if ( result < 0 )
1707 return result;
1708 retres1 = do_read_current_netcnf_nodecode(fpath, &ptr);
1709 if ( retres1 <= 0 )
1710 return (!retres1) ? -3 : retres1;
1711 heapmem = (char *)do_alloc_heapmem((int)((unsigned int)retres1 + strlen(usrname_bufnew) + 1));
1712 if ( !heapmem )
1713 {
1714 do_free_heapmem(ptr);
1715 return -2;
1716 }
1717 ptr_1 = ptr;
1718 heapmem_1 = heapmem;
1719 while ( *ptr_1 )
1720 {
1721 if ( do_type_check(type, ptr_1) > 0 && !do_split_str_comma_index(g_arg_fname, ptr_1, 3) )
1722 {
1723 if ( !strcmp(g_arg_fname, usrname_buf2) )
1724 {
1725 if ( !do_split_str_comma_index(g_arg_fname, ptr_1, 2) )
1726 {
1727 heapmem_1 += sprintf(heapmem_1, "%d,%d,%s,%s\n", type, 1, g_arg_fname, g_combination_buf1);
1728 ptr_1 = do_get_str_line(ptr_1);
1729 continue;
1730 }
1731 }
1732 else if ( !strcmp(g_arg_fname, g_combination_buf1) )
1733 {
1734 do_free_heapmem(ptr);
1735 do_free_heapmem(heapmem);
1736 return -11;
1737 }
1738 }
1739 for ( ; *ptr_1 && *ptr_1 != '\n'; ptr_1 += 1 )
1740 {
1741 *heapmem_1 = *ptr_1;
1742 heapmem_1 += 1;
1743 }
1744 if ( *ptr_1 == '\n' )
1745 {
1746 *heapmem_1 = *ptr_1;
1747 heapmem_1 += 1;
1748 ptr_1 += 1;
1749 }
1750 }
1751 do_free_heapmem(ptr);
1752 writeres1 = do_write_noencode_netcnf_atomic(fpath, heapmem, (int)(heapmem_1 - heapmem));
1753 do_free_heapmem(heapmem);
1754 return writeres1;
1755}
1756
1757static int do_edit_entry_inner(
1758 const char *fname,
1759 int type,
1760 const char *usr_name,
1761 const char *new_usr_name,
1762 sceNetCnfEnv_t *e,
1763 const char *icon_value,
1764 const char *iconsys_value,
1765 int no_check_capacity)
1766{
1767 int result;
1768 int rmoldcfgres;
1769 const char *curentry1;
1770 char curentrybuf1[256];
1771 char curfilepath1[256];
1772
1773 if ( get_check_provider_eq_zero() )
1774 {
1775 result = do_check_provider_inner(e, type);
1776 if ( result < 0 )
1777 return result;
1778 }
1779 result = do_handle_fname(g_dir_name, sizeof(g_dir_name), fname);
1780 if ( result < 0 )
1781 return result;
1782 if ( !no_check_capacity )
1783 {
1784 result = do_check_capacity_inner(g_dir_name);
1785 if ( result < 0 )
1786 return result;
1787 }
1788 result = do_handle_combination_path(type, g_dir_name, g_combination_buf2, sizeof(g_combination_buf2), usr_name);
1789 if ( result < 0 )
1790 return result;
1791 result = do_read_current_netcnf_nodecode(g_dir_name, &g_edit_entry_heapptr);
1792 if ( result <= 0 )
1793 {
1794 return !result ? -3 : result;
1795 }
1796 rmoldcfgres = do_remove_old_config(g_dir_name, g_edit_entry_heapptr, icon_value, iconsys_value);
1797 if ( rmoldcfgres >= 0 )
1798 {
1799 int flg;
1800
1801 rmoldcfgres = 0;
1802 for ( curentry1 = g_edit_entry_heapptr; *curentry1; curentry1 = do_get_str_line(curentry1) )
1803 {
1804 if (
1805 do_type_check(type, curentry1) > 0 && !do_split_str_comma_index(g_arg_fname, curentry1, 3)
1806 && !strcmp(g_arg_fname, g_combination_buf2) && !do_split_str_comma_index(curentrybuf1, curentry1, 2) )
1807 {
1808 rmoldcfgres += 1;
1809 }
1810 }
1811 flg = 0;
1812 if ( !rmoldcfgres )
1813 {
1814 rmoldcfgres = -8;
1815 }
1816 else
1817 {
1818 if ( !get_check_provider_eq_zero() )
1819 {
1820 flg = 1;
1821 }
1822 if ( !flg )
1823 {
1824 rmoldcfgres = !do_handle_netcnf_dirname(g_dir_name, curentrybuf1, curfilepath1) ?
1825 -11 :
1826 do_read_check_netcnf(curfilepath1, type, e->f_no_check_magic, e->f_no_decode);
1827 }
1828 }
1829 if ( flg || rmoldcfgres >= 0 )
1830 {
1831 do_safe_make_name(curfilepath1, sizeof(curfilepath1), curentrybuf1, ".tmp");
1832 e->dir_name = g_dir_name;
1833 // cppcheck-suppress autoVariables
1834 e->arg_fname = curfilepath1;
1835 e->req = type ? 2 : 1;
1836 if ( do_export_netcnf(e) )
1837 {
1838 rmoldcfgres = -1;
1839 }
1840 else
1841 {
1842 char *curfilepath1end;
1843
1844 do_safe_strcpy(curfilepath1, sizeof(curfilepath1), g_dir_name, 1010);
1845 for ( curfilepath1end = &curfilepath1[strlen(curfilepath1)]; curfilepath1end != curfilepath1;
1846 curfilepath1end -= 1 )
1847 {
1848 if ( *curfilepath1end == '/' || *curfilepath1end == '\\' )
1849 {
1850 curfilepath1end[1] = 0;
1851 break;
1852 }
1853 }
1854 do_safe_strcat(curfilepath1, sizeof(curfilepath1), curentrybuf1, 1017);
1855 do_safe_strcpy(curentrybuf1, sizeof(curentrybuf1), curfilepath1, 1018);
1856 do_safe_strcat(curfilepath1, sizeof(curfilepath1), ".tmp", 1019);
1857 if ( iomanX_rename(curfilepath1, curentrybuf1) == -EIO )
1858 rmoldcfgres = -18;
1859 }
1860 }
1861 }
1862 do_free_heapmem(g_edit_entry_heapptr);
1863 if ( rmoldcfgres >= 0 )
1864 {
1865 do_set_latest_entry_inner(g_dir_name, type, g_combination_buf2);
1866 if ( new_usr_name )
1867 rmoldcfgres = do_handle_set_usrname(g_dir_name, type, g_combination_buf2, new_usr_name);
1868 }
1869 return (!strncmp(g_dir_name, "pfs", 3) && iomanX_sync(g_dir_name, 0) == -EIO) ? -18 : rmoldcfgres;
1870}
1871
1872static int do_delete_entry_inner(
1873 const char *fname,
1874 int type,
1875 const char *usr_name,
1876 const char *icon_value,
1877 const char *iconsys_value,
1878 int no_check_capacity)
1879{
1880 int has_comma;
1881 int result;
1882 char *heapmem;
1883 const char *curentry1;
1884
1885 has_comma = 0;
1886 g_delete_entry_heapptr = 0;
1887 result = do_handle_fname(g_dir_name, sizeof(g_dir_name), fname);
1888 if ( result < 0 )
1889 {
1890 return result;
1891 }
1892 if ( !no_check_capacity )
1893 {
1894 result = do_check_capacity_inner(g_dir_name);
1895 if ( result < 0 )
1896 return result;
1897 }
1898 result = do_handle_combination_path(type, g_dir_name, g_combination_buf1, sizeof(g_combination_buf1), usr_name);
1899 if ( result < 0 )
1900 return result;
1901 result = do_read_current_netcnf_nodecode(g_dir_name, &g_delete_entry_heapptr);
1902 if ( result <= 0 )
1903 return !result ? -3 : result;
1904 heapmem = (char *)do_alloc_heapmem(result);
1905 if ( !heapmem )
1906 {
1907 do_free_heapmem(g_delete_entry_heapptr);
1908 return -2;
1909 }
1910 result = do_remove_old_config(g_dir_name, g_delete_entry_heapptr, icon_value, iconsys_value);
1911 if ( result >= 0 )
1912 {
1913 char *heapmem_1;
1914
1915 curentry1 = g_delete_entry_heapptr;
1916 heapmem_1 = heapmem;
1917 while ( *curentry1 )
1918 {
1919 if (
1920 do_type_check(type, curentry1) <= 0 || do_split_str_comma_index(g_arg_fname, curentry1, 3)
1921 || strcmp(g_arg_fname, g_combination_buf1) )
1922 {
1923 for ( ; *curentry1 && *curentry1 != '\n'; curentry1 += 1 )
1924 {
1925 *heapmem_1 = *curentry1;
1926 heapmem_1 += 1;
1927 }
1928 if ( *curentry1 == '\n' )
1929 {
1930 *heapmem_1 = *curentry1;
1931 heapmem_1 += 1;
1932 curentry1 += 1;
1933 }
1934 }
1935 else
1936 {
1937 if ( !do_split_str_comma_index(g_entry_buffer, curentry1, 2) )
1938 has_comma = 1;
1939 curentry1 = do_get_str_line(curentry1);
1940 }
1941 }
1942 result = do_write_noencode_netcnf_atomic(g_dir_name, heapmem, (int)(heapmem_1 - heapmem));
1943 if ( result >= 0 && has_comma )
1944 result = do_remove_netcnf_dirname(g_dir_name, g_entry_buffer);
1945 }
1946 do_free_heapmem(g_delete_entry_heapptr);
1947 do_free_heapmem(heapmem);
1948 return (!strncmp(g_dir_name, "pfs", 3) && iomanX_sync(g_dir_name, 0) == -EIO) ? -18 : result;
1949}
1950
1951static int do_set_latest_entry_inner(const char *fname, int type, const char *usr_name)
1952{
1953 int isbeforeend1;
1954 int result;
1955 char *heapmem2;
1956 int readsz;
1957 char *heapmem1;
1958 char *heapmem1_1;
1959 char *curentry1;
1960
1961 isbeforeend1 = 0;
1962 result = do_handle_fname(g_dir_name, sizeof(g_dir_name), fname);
1963 if ( result < 0 )
1964 {
1965 return result;
1966 }
1967 result = do_handle_combination_path(type, g_dir_name, g_combination_buf1, sizeof(g_combination_buf1), usr_name);
1968 heapmem2 = 0;
1969 if ( result < 0 )
1970 {
1971 return result;
1972 }
1973 g_set_latest_entry_heapptr = 0;
1974 result = do_read_current_netcnf_nodecode(g_dir_name, &g_set_latest_entry_heapptr);
1975 readsz = result;
1976 if ( result <= 0 )
1977 {
1978 return !result ? -3 : result;
1979 }
1980 result = -2;
1981 heapmem1 = (char *)do_alloc_heapmem(readsz);
1982 heapmem1_1 = heapmem1;
1983 if ( heapmem1 )
1984 {
1985 char *heapmem2_1;
1986
1987 heapmem2 = (char *)do_alloc_heapmem(readsz);
1988 heapmem2_1 = heapmem2;
1989 if ( heapmem2 )
1990 {
1991 curentry1 = g_set_latest_entry_heapptr;
1992 result = 0;
1993 while ( *curentry1 )
1994 {
1995 if (
1996 do_type_check(type, curentry1) > 0 && !do_split_str_comma_index(g_arg_fname, curentry1, 3)
1997 && !strcmp(g_arg_fname, g_combination_buf1) )
1998 {
1999 for ( ; *curentry1 && *curentry1 != '\n'; curentry1 += 1 )
2000 {
2001 *heapmem1_1 = *curentry1;
2002 heapmem1_1 += 1;
2003 }
2004 if ( *curentry1 == '\n' )
2005 {
2006 *heapmem1_1 = *curentry1;
2007 heapmem1_1 += 1;
2008 curentry1 += 1;
2009 }
2010 result += 1;
2011 if ( heapmem2 < heapmem2_1 )
2012 isbeforeend1 = 1;
2013 }
2014 else
2015 {
2016 for ( ; *curentry1 && *curentry1 != '\n'; curentry1 += 1 )
2017 {
2018 *heapmem2_1 = *curentry1;
2019 heapmem2_1 += 1;
2020 }
2021 if ( *curentry1 == '\n' )
2022 {
2023 *heapmem2_1 = *curentry1;
2024 heapmem2_1 += 1;
2025 curentry1 += 1;
2026 }
2027 }
2028 }
2029 if ( isbeforeend1 )
2030 {
2031 memcpy(heapmem1_1, heapmem2, (u32)(heapmem2_1 - heapmem2));
2032 result =
2033 do_write_noencode_netcnf_atomic(g_dir_name, heapmem1, (int)(heapmem1_1 - heapmem1 + heapmem2_1 - heapmem2));
2034 }
2035 }
2036 }
2037 do_free_heapmem(g_set_latest_entry_heapptr);
2038 do_free_heapmem(heapmem1);
2039 do_free_heapmem(heapmem2);
2040 return (!strncmp(g_dir_name, "pfs", 3) && iomanX_sync(g_dir_name, 0) == -EIO) ? -18 : result;
2041}
2042
2043static int do_delete_all_inner(const char *dev)
2044{
2045 int i;
2046 int dread_res;
2047 iox_dirent_t statname;
2048
2049 if ( !strncmp(dev, "mc", 2) )
2050 {
2051 int dfd1;
2052
2053 for ( i = 0; dev[i] != ':'; i += 1 )
2054 {
2055 g_netcnf_file_path[i] = dev[i];
2056 }
2057 g_netcnf_file_path[i] = dev[i];
2058 g_netcnf_file_path[i + 1] = 0;
2059 do_safe_strcat(g_netcnf_file_path, sizeof(g_netcnf_file_path), "/BWNETCNF", 1199);
2060 dfd1 = do_dopen_wrap(g_netcnf_file_path);
2061 // cppcheck-suppress knownConditionTrueFalse
2062 if ( dfd1 < 0 )
2063 return 0;
2064 while ( 1 )
2065 {
2066 dread_res = do_dread_wrap(dfd1, &statname);
2067 // cppcheck-suppress knownConditionTrueFalse
2068 if ( dread_res <= 0 )
2069 break;
2070 if ( strcmp(statname.name, ".") && strcmp(statname.name, "..") )
2071 {
2072 do_safe_make_pathname(g_dir_name, sizeof(g_dir_name), g_netcnf_file_path, statname.name);
2073 if ( do_remove_wrap(g_dir_name) < 0 )
2074 {
2075 do_dclose_wrap(dfd1);
2076 return -7;
2077 }
2078 }
2079 }
2080 do_dclose_wrap(dfd1);
2081 return (rmdir(g_netcnf_file_path) < 0) ? -7 : 0;
2082 }
2083 else if ( !strncmp(dev, "pfs", 3) )
2084 {
2085 int dfd2;
2086 int remove_res2;
2087 int rmdir_res1;
2088
2089 for ( i = 0; dev[i] != ':'; i += 1 )
2090 {
2091 g_netcnf_file_path[i] = dev[i];
2092 }
2093 g_netcnf_file_path[i] = dev[i];
2094 g_netcnf_file_path[i + 1] = 0;
2095 do_safe_strcat(g_netcnf_file_path, sizeof(g_netcnf_file_path), "/etc/network", 1229);
2096 dfd2 = do_dopen_wrap(g_netcnf_file_path);
2097 // cppcheck-suppress knownConditionTrueFalse
2098 if ( dfd2 < 0 )
2099 {
2100 return (dfd2 == -EIO) ? -18 : 0;
2101 }
2102 while ( 1 )
2103 {
2104 dread_res = do_dread_wrap(dfd2, &statname);
2105 // cppcheck-suppress knownConditionTrueFalse
2106 if ( dread_res <= 0 )
2107 break;
2108 if ( strcmp(statname.name, ".") && strcmp(statname.name, "..") )
2109 {
2110 do_safe_make_pathname(g_dir_name, sizeof(g_dir_name), g_netcnf_file_path, statname.name);
2111 remove_res2 = do_remove_wrap(g_dir_name);
2112 if ( remove_res2 < 0 )
2113 {
2114 do_dclose_wrap(dfd2);
2115 return (remove_res2 == -EIO) ? -18 : -7;
2116 }
2117 }
2118 }
2119 if ( dread_res == -EIO )
2120 {
2121 do_dclose_wrap(dfd2);
2122 return -18;
2123 }
2124 do_dclose_wrap(dfd2);
2125 rmdir_res1 = rmdir(g_netcnf_file_path);
2126 return (rmdir_res1 >= 0) ? ((iomanX_sync(g_netcnf_file_path, 0) != -EIO) ? 0 : -18) :
2127 ((rmdir_res1 == -EIO) ? -18 : -7);
2128 }
2129 return -17;
2130}
2131
2132static int do_check_special_provider_inner(const char *fname, int type, const char *usr_name, sceNetCnfEnv_t *e)
2133{
2134 int result;
2135 const char *curentry1;
2136 int curentcount;
2137 int retres;
2138
2139 result = do_handle_fname(g_dir_name, sizeof(g_dir_name), fname);
2140 if ( result < 0 )
2141 return result;
2142 result = do_handle_combination_path(type, g_dir_name, g_combination_buf2, sizeof(g_combination_buf2), usr_name);
2143 if ( result < 0 )
2144 return result;
2145 result = do_read_current_netcnf_nodecode(g_dir_name, &g_check_special_provider_heapptr);
2146 if ( result <= 0 )
2147 {
2148 return !result ? -3 : result;
2149 }
2150 curentcount = 0;
2151 for ( curentry1 = g_check_special_provider_heapptr; *curentry1; curentry1 = do_get_str_line(curentry1) )
2152 {
2153 if (
2154 do_type_check(type, curentry1) > 0 && !do_split_str_comma_index(g_arg_fname, curentry1, 3)
2155 && !strcmp(g_arg_fname, g_combination_buf2) && !do_split_str_comma_index((char *)e->lbuf, curentry1, 2) )
2156 {
2157 curentcount += 1;
2158 }
2159 }
2160 retres = curentcount ? ((do_handle_netcnf_dirname(g_dir_name, (const char *)e->lbuf, (char *)e->dbuf)) ?
2161 do_read_check_netcnf((const char *)e->dbuf, type, e->f_no_check_magic, e->f_no_decode) :
2162 -11) :
2163 -8;
2164 do_free_heapmem(g_check_special_provider_heapptr);
2165 return retres;
2166}
2167
2168static char *do_alloc_mem_inner(sceNetCnfEnv_t *e, unsigned int size, int align)
2169{
2170 void *mem_ptr;
2171 char *retptrbegin;
2172
2173 mem_ptr = e->mem_ptr;
2174 if ( !mem_ptr )
2175 {
2176 e->alloc_err += 1;
2177 return 0;
2178 }
2179 retptrbegin = (char *)(((uiptr)mem_ptr + (1 << align) - 1) & (uiptr) ~((1 << align) - 1));
2180 if ( &retptrbegin[size] >= (char *)e->mem_last )
2181 {
2182 e->alloc_err += 1;
2183 return 0;
2184 }
2185 e->mem_ptr = &retptrbegin[size];
2186 memset(retptrbegin, 0, size);
2187 return retptrbegin;
2188}
2189
2190static const char *do_netcnf_parse_string(sceNetCnfEnv_t *e, const char *e_arg)
2191{
2192 u8 *dbuf;
2193 const char *argbegin;
2194 int i;
2195 int hexnum;
2196 int err;
2197
2198 dbuf = e->dbuf;
2199 if ( *e_arg != '"' )
2200 return e_arg;
2201 err = 0;
2202 for ( argbegin = e_arg + 1; *argbegin && *argbegin != '"' && (char *)(dbuf + 1) < (char *)&(e->dbuf[1023]); )
2203 {
2204 char argchr_1;
2205
2206 argchr_1 = *argbegin;
2207 argbegin += 1;
2208 if ( argchr_1 == '\\' )
2209 {
2210 if ( !*argbegin )
2211 {
2212 err = 1;
2213 break;
2214 }
2215 argchr_1 = 0;
2216 if ( (unsigned int)(((u8)*argbegin) - '0') >= 8 )
2217 {
2218 if ( ((u8)*argbegin) == 'x' || ((u8)*argbegin) == 'X' )
2219 {
2220 argbegin += 1;
2221 argchr_1 = 0;
2222 if ( !isxdigit(*argbegin) )
2223 {
2224 err = 2;
2225 break;
2226 }
2227 for ( i = 0; i < 2 && isxdigit(*argbegin); i += 1 )
2228 {
2229 hexnum = 16 * argchr_1;
2230 argchr_1 =
2231 (char)(hexnum
2232 + (isdigit(*argbegin) ? (((u8)*argbegin) - '0') : ((!islower(*argbegin)) ? ((u8)*argbegin) - '7' : ((u8)*argbegin) - 'W')));
2233 argbegin += 1;
2234 }
2235 }
2236 else
2237 {
2238 argchr_1 = *argbegin;
2239 argbegin += 1;
2240 switch ( argchr_1 )
2241 {
2242 case 'a':
2243 argchr_1 = 7;
2244 break;
2245 case 'b':
2246 argchr_1 = 8;
2247 break;
2248 case 'f':
2249 argchr_1 = 12;
2250 break;
2251 case 'n':
2252 argchr_1 = 10;
2253 break;
2254 case 'r':
2255 argchr_1 = 13;
2256 break;
2257 case 't':
2258 argchr_1 = 9;
2259 break;
2260 case 'v':
2261 argchr_1 = 11;
2262 break;
2263 default:
2264 break;
2265 }
2266 }
2267 }
2268 else
2269 {
2270 for ( i = 0; i < 3 && (((u8)*argbegin) - (unsigned int)'0' < 8); i += 1 )
2271 {
2272 argchr_1 = 8 * argchr_1 + *argbegin - '0';
2273 argbegin += 1;
2274 }
2275 }
2276 }
2277 else if ( (unsigned int)(argchr_1 - 129) < 0x1F || (unsigned int)(argchr_1 - 224) < 0x1D )
2278 {
2279 if ( (u8)(((u8)*argbegin) - 64) < 0xBDu && ((u8)*argbegin) != 127 )
2280 {
2281 *dbuf = (u8)argchr_1;
2282 dbuf += 1;
2283 argchr_1 = *argbegin;
2284 argbegin += 1;
2285 }
2286 }
2287 *dbuf = (u8)argchr_1;
2288 dbuf += 1;
2289 }
2290 if ( !err )
2291 {
2292 if ( ((u8)*argbegin) != '"' )
2293 {
2294 err = 3;
2295 }
2296 else if ( argbegin[1] )
2297 {
2298 err = 4;
2299 }
2300 }
2301 if ( err )
2302 {
2303 printf("netcnf: \"%s\" line %d: ", e->fname, e->lno);
2304 switch ( err )
2305 {
2306 case 1:
2307 printf("invalid escape (%s)", e_arg);
2308 break;
2309 case 2:
2310 printf("missing hexa-decimal(%s)", e_arg);
2311 break;
2312 case 3:
2313 printf("invalid quote (%s)", e_arg);
2314 break;
2315 case 4:
2316 printf("invalid extra chars (%s)", e_arg);
2317 break;
2318 default:
2319 break;
2320 }
2321 printf("\n");
2322 e->syntax_err += 1;
2323 return 0;
2324 }
2325 *dbuf = 0;
2326 return (const char *)e->dbuf;
2327}
2328
2329static char *do_alloc_mem_for_write(sceNetCnfEnv_t *e, const char *str)
2330{
2331 char *strptr;
2332
2333 strptr = do_alloc_mem_inner(e, (unsigned int)strlen(str) + 1, 0);
2334 if ( !strptr )
2335 return 0;
2336 strcpy(strptr, str);
2337 return strptr;
2338}
2339
2340static char *do_check_e_arg(sceNetCnfEnv_t *e, const char *e_arg)
2341{
2342 const char *strptr;
2343
2344 strptr = do_netcnf_parse_string(e, e_arg);
2345 return strptr ? do_alloc_mem_for_write(e, strptr) : 0;
2346}
2347
2348static int do_parse_number(sceNetCnfEnv_t *e, const char *e_arg, unsigned int *n_result)
2349{
2350 const char *e_arg_1;
2351 unsigned int curbasex;
2352 unsigned int curnum;
2353
2354 e_arg_1 = e_arg;
2355 curbasex = 10;
2356 if ( *e_arg == '0' && e_arg[1] )
2357 {
2358 e_arg_1 = e_arg + 1;
2359 curbasex = 8;
2360 if ( e_arg[1] == 'x' )
2361 {
2362 e_arg_1 = e_arg + 2;
2363 curbasex = 16;
2364 }
2365 }
2366 curnum = 0;
2367 if ( *e_arg_1 )
2368 {
2369 while ( 1 )
2370 {
2371 u32 e_arg_1_num;
2372
2373 e_arg_1_num = (((u8)*e_arg_1)) - '0';
2374 if ( ((u8)*e_arg_1) - (unsigned int)'0' >= 0xA )
2375 {
2376 e_arg_1_num = (((u8)*e_arg_1)) - 'W';
2377 if ( ((u8)*e_arg_1) - (unsigned int)'a' >= 6 )
2378 break;
2379 }
2380 if ( e_arg_1_num >= curbasex )
2381 break;
2382 e_arg_1 += 1;
2383 curnum = curnum * curbasex + e_arg_1_num;
2384 if ( !*e_arg_1 )
2385 {
2386 *n_result = curnum;
2387 return 0;
2388 }
2389 }
2390 }
2391 printf("netcnf: \"%s\" line %d: ", e->fname, e->lno);
2392 printf("invalid digit (%s)", e_arg);
2393 printf("\n");
2394 e->syntax_err += 1;
2395 return -1;
2396}
2397
2398static int do_netcnfname2address_wrap(sceNetCnfEnv_t *e, const char *buf, sceNetCnfAddress_t *paddr)
2399{
2400 int errret;
2401
2402 errret = sceNetCnfName2Address(paddr, buf);
2403 if ( errret < 0 )
2404 {
2405 printf("netcnf: \"%s\" line %d: ", e->fname, e->lno);
2406 printf("sceNetCnfName2Address(%s) -> %d\n", buf, errret);
2407 printf("\n");
2408 e->syntax_err += 1;
2409 return -1;
2410 }
2411 return 0;
2412}
2413
2414static int do_parse_phone_argument(sceNetCnfEnv_t *e, int opt_argc, const char **opt_argv, unsigned int *p_result)
2415{
2416 int i;
2417 unsigned int bitflags1;
2418 unsigned int numval;
2419
2420 bitflags1 = 0;
2421 for ( i = 0; i < opt_argc; i += 1 )
2422 {
2423 if ( !strcmp("phase", opt_argv[i]) )
2424 {
2425 bitflags1 |= 1;
2426 }
2427 else if ( !strcmp("cp", opt_argv[i]) )
2428 {
2429 bitflags1 |= 2;
2430 }
2431 else if ( !strcmp("auth", opt_argv[i]) )
2432 {
2433 bitflags1 |= 4;
2434 }
2435 else if ( !strcmp("chat", opt_argv[i]) )
2436 {
2437 bitflags1 |= 8;
2438 }
2439 else if ( !strcmp("private", opt_argv[i]) )
2440 {
2441 bitflags1 |= 0x10;
2442 }
2443 else if ( !strcmp("dll", opt_argv[i]) )
2444 {
2445 bitflags1 |= 0x20;
2446 }
2447 else if ( !strcmp("dump", opt_argv[i]) )
2448 {
2449 bitflags1 |= 0x40;
2450 }
2451 else if ( !strcmp("timer", opt_argv[i]) )
2452 {
2453 bitflags1 |= 0x10000;
2454 }
2455 else if ( !strcmp("event", opt_argv[i]) )
2456 {
2457 bitflags1 |= 0x20000;
2458 }
2459 else if ( do_parse_number(e, opt_argv[i], &numval) )
2460 return -1;
2461 }
2462 *p_result = bitflags1;
2463 return 0;
2464}
2465
2466static int do_check_interface_keyword(
2467 sceNetCnfEnv_t *e, const char *display_name_arg, const char *attach_ifc_arg, const char *attach_dev_arg)
2468{
2469 struct sceNetCnfPair *cnfpair1;
2470 struct sceNetCnfPair *pair_tail;
2471
2472 cnfpair1 = (sceNetCnfPair_t *)do_alloc_mem_inner(e, sizeof(sceNetCnfPair_t), 2);
2473 if ( !cnfpair1 )
2474 return -1;
2475 cnfpair1->display_name = (u8 *)do_check_e_arg(e, display_name_arg);
2476 if ( !cnfpair1->display_name )
2477 return -1;
2478 cnfpair1->attach_ifc = (u8 *)do_check_e_arg(e, attach_ifc_arg);
2479 if ( !cnfpair1->attach_ifc )
2480 return -1;
2481 if ( attach_dev_arg && *attach_dev_arg )
2482 {
2483 cnfpair1->attach_dev = (u8 *)do_check_e_arg(e, attach_dev_arg);
2484 if ( !cnfpair1->attach_dev )
2485 return -1;
2486 }
2487 pair_tail = e->root->pair_tail;
2488 cnfpair1->back = pair_tail;
2489 if ( !pair_tail )
2490 pair_tail = (sceNetCnfPair_t *)e->root;
2491 pair_tail->forw = cnfpair1;
2492 cnfpair1->forw = 0;
2493 e->root->pair_tail = cnfpair1;
2494 return 0;
2495}
2496
2497static int do_check_nameserver(sceNetCnfEnv_t *e, struct sceNetCnfInterface *ifc, int opt_argc, const char **opt_argv)
2498{
2499 int addordel;
2500 nameserver_t *nameservermem_1;
2501
2502 if ( opt_argc < 3 )
2503 return 0;
2504
2505 if ( !strcmp("add", opt_argv[1]) )
2506 addordel = 1;
2507 else if ( !strcmp("del", opt_argv[1]) )
2508 addordel = 2;
2509 else
2510 return 0;
2511 nameservermem_1 = (nameserver_t *)do_alloc_mem_inner(e, sizeof(nameserver_t), 2);
2512 if ( !nameservermem_1 )
2513 return -1;
2514 nameservermem_1->cmd.code = addordel;
2515 if ( do_netcnfname2address_wrap(e, opt_argv[2], &nameservermem_1->address) )
2516 return -1;
2517 nameservermem_1->cmd.back = ifc->cmd_tail;
2518 if ( ifc->cmd_tail )
2519 ifc->cmd_tail->forw = &nameservermem_1->cmd;
2520 else
2521 ifc->cmd_head = &nameservermem_1->cmd;
2522 nameservermem_1->cmd.forw = 0;
2523 ifc->cmd_tail = &nameservermem_1->cmd;
2524 return 0;
2525}
2526
2527static int do_check_route(sceNetCnfEnv_t *e, struct sceNetCnfInterface *ifc, int opt_argc, const char **opt_argv)
2528{
2529 int addordel;
2530 route_t *route_mem_1;
2531 int i;
2532
2533 if ( opt_argc < 3 )
2534 return 0;
2535 if ( !strcmp("add", opt_argv[1]) )
2536 addordel = 3;
2537 else if ( !strcmp("del", opt_argv[1]) )
2538 addordel = 4;
2539 else
2540 return 0;
2541 route_mem_1 = (route_t *)do_alloc_mem_inner(e, sizeof(route_t), 2);
2542 if ( !route_mem_1 )
2543 return -1;
2544 i = 2;
2545 route_mem_1->cmd.code = addordel;
2546 if ( !strcmp("-net", opt_argv[i]) )
2547 {
2548 i += 1;
2549 route_mem_1->re.flags &= ~2;
2550 }
2551 else if ( !strcmp("-host", opt_argv[i]) )
2552 {
2553 i += 1;
2554 route_mem_1->re.flags |= 2;
2555 }
2556 if ( i >= opt_argc )
2557 return 0;
2558 if ( do_netcnfname2address_wrap(e, 0, &route_mem_1->re.dstaddr) )
2559 return -1;
2560 if ( do_netcnfname2address_wrap(e, 0, &route_mem_1->re.gateway) )
2561 return -1;
2562 if ( do_netcnfname2address_wrap(e, 0, &route_mem_1->re.genmask) )
2563 return -1;
2564 if ( (strcmp("default", opt_argv[i])
2565 && do_netcnfname2address_wrap(e, (const char *)opt_argv[i], &route_mem_1->re.dstaddr)) )
2566 return -1;
2567 i += 1;
2568 for ( ; i < opt_argc; i += 2 )
2569 {
2570 if ( !strcmp("gw", opt_argv[i]) )
2571 {
2572 if ( do_netcnfname2address_wrap(e, opt_argv[i + 1], &route_mem_1->re.gateway) )
2573 return -1;
2574 route_mem_1->re.flags |= 4;
2575 }
2576 else if ( !strcmp("netmask", opt_argv[i]) )
2577 {
2578 if ( do_netcnfname2address_wrap(e, opt_argv[i + 1], &route_mem_1->re.genmask) )
2579 return -1;
2580 }
2581 }
2582 route_mem_1->cmd.back = ifc->cmd_tail;
2583 if ( ifc->cmd_tail )
2584 ifc->cmd_tail->forw = &route_mem_1->cmd;
2585 else
2586 ifc->cmd_head = &route_mem_1->cmd;
2587 route_mem_1->cmd.forw = 0;
2588 ifc->cmd_tail = &route_mem_1->cmd;
2589 return 0;
2590}
2591
2592static void do_init_ifc_inner(sceNetCnfInterface_t *ifc)
2593{
2594 const struct netcnf_option *curentry1;
2595
2596 for ( curentry1 = g_options_attach_cnf; curentry1->m_key; curentry1 += 1 )
2597 {
2598 switch ( curentry1->m_type )
2599 {
2600 case '1':
2601 case 'b':
2602 case 'c':
2603 *((char *)ifc + curentry1->m_offset) = 0xFF;
2604 break;
2605 case '4':
2606 case 'D':
2607 case 'L':
2608 case 'P':
2609 case 'T':
2610 *(u32 *)((char *)ifc + curentry1->m_offset) = 0xFFFFFFFF;
2611 break;
2612 default:
2613 break;
2614 }
2615 }
2616}
2617
2618static int do_check_args(sceNetCnfEnv_t *e, struct sceNetCnfUnknownList *unknown_list)
2619{
2620 unsigned int lenx1;
2621 int i;
2622 struct sceNetCnfUnknown *listtmp;
2623 struct sceNetCnfUnknown *cpydst_1;
2624
2625 lenx1 = 0;
2626 for ( i = 0; i < e->ac; i += 1 )
2627 {
2628 lenx1 += 3 + strlen(e->av[i]);
2629 }
2630 listtmp = (sceNetCnfUnknown_t *)do_alloc_mem_inner(e, sizeof(sceNetCnfUnknown_t) + lenx1, 2);
2631 if ( !listtmp )
2632 return -1;
2633 cpydst_1 = listtmp + 1;
2634 for ( i = 0; i < e->ac; i += 1 )
2635 {
2636 unsigned int cpysz;
2637
2638 cpysz = (unsigned int)strlen(e->av[i]);
2639 memcpy(cpydst_1, e->av[i], cpysz);
2640 ((char *)cpydst_1)[cpysz] = 32 * (i < e->ac - 1);
2641 cpydst_1 = (struct sceNetCnfUnknown *)&((char *)cpydst_1)[cpysz + 1];
2642 }
2643 listtmp->back = unknown_list->tail;
2644 if ( unknown_list->tail )
2645 unknown_list->tail->forw = listtmp;
2646 else
2647 unknown_list->head = listtmp;
2648 listtmp->forw = 0;
2649 unknown_list->tail = listtmp;
2650 return 0;
2651}
2652
2653static int do_check_other_keywords(
2654 sceNetCnfEnv_t *e, const struct netcnf_option *options, void *cnfdata, struct sceNetCnfUnknownList *unknown_list)
2655{
2656 int wasprefixed;
2657 unsigned int numval;
2658
2659 wasprefixed = (e->av[0][0] == '-') ? 1 : 0;
2660 if ( e->av[0][wasprefixed] )
2661 {
2662 for ( ; options->m_key && strcmp(&(e->av[0])[wasprefixed], options->m_key); options += 1 )
2663 ;
2664 if ( !options->m_key )
2665 return do_check_args(e, unknown_list);
2666 switch ( options->m_type )
2667 {
2668 case '1':
2669 numval = 0xFF;
2670 if ( !wasprefixed && (e->ac < 2 || do_parse_number(e, e->av[1], &numval)) )
2671 break;
2672 *((u8 *)cnfdata + options->m_offset) = (u8)numval;
2673 return 0;
2674 case '4':
2675 numval = 0xFFFFFFFF;
2676 if ( !wasprefixed && (e->ac < 2 || do_parse_number(e, e->av[1], &numval)) )
2677 break;
2678 *(u32 *)((char *)cnfdata + options->m_offset) = numval;
2679 return 0;
2680 case 'A':
2681 if ( !wasprefixed )
2682 {
2683 if ( e->ac < 2 )
2684 break;
2685 if ( !strcmp("any", (const char *)e->av[1]) )
2686 {
2687 numval = 0;
2688 }
2689 else if ( !strcmp("pap", (const char *)e->av[1]) )
2690 {
2691 numval = 1;
2692 }
2693 else if ( !strcmp("chap", (const char *)e->av[1]) )
2694 {
2695 numval = 2;
2696 }
2697 else if ( !strcmp("pap/chap", (const char *)e->av[1]) )
2698 {
2699 numval = 3;
2700 }
2701 else if ( !strcmp("chap/pap", (const char *)e->av[1]) )
2702 {
2703 numval = 4;
2704 }
2705 else if ( do_parse_number(e, e->av[1], &numval) )
2706 {
2707 return -1;
2708 }
2709 *((u8 *)cnfdata + options->m_offset) = (u8)numval;
2710 }
2711 if ( !strcmp("want.auth", (const char *)e->av[0]) )
2712 *((u8 *)cnfdata + 171) = !wasprefixed;
2713 else
2714 *((u8 *)cnfdata + 247) = !wasprefixed;
2715 return 0;
2716 case 'C':
2717 if ( !wasprefixed )
2718 {
2719 if ( e->ac < 2 || do_parse_number(e, e->av[1], &numval) )
2720 break;
2721 *(u32 *)((char *)cnfdata + options->m_offset) = numval;
2722 }
2723 if ( !strcmp("want.accm", (const char *)e->av[0]) )
2724 *((u8 *)cnfdata + 170) = !wasprefixed;
2725 else
2726 *((u8 *)cnfdata + 246) = !wasprefixed;
2727 return 0;
2728 case 'D':
2729 numval = 0xFFFFFFFF;
2730 if ( !wasprefixed )
2731 {
2732 if ( e->ac < 2 )
2733 break;
2734 if ( !strcmp("tone", (const char *)e->av[1]) )
2735 {
2736 numval = 0;
2737 }
2738 else if ( !strcmp("pulse", (const char *)e->av[1]) )
2739 {
2740 numval = 1;
2741 }
2742 else if ( !strcmp("any", (const char *)e->av[1]) )
2743 {
2744 numval = 2;
2745 }
2746 else if ( do_parse_number(e, e->av[1], &numval) )
2747 {
2748 return -1;
2749 }
2750 }
2751 *(u32 *)((char *)cnfdata + options->m_offset) = numval;
2752 return 0;
2753 case 'L':
2754 numval = 0xFFFFFFFF;
2755 if ( !wasprefixed && do_parse_phone_argument(e, e->ac - 1, (const char **)&e->av[1], &numval) )
2756 return -1;
2757 *(u32 *)((char *)cnfdata + options->m_offset) = numval;
2758 return 0;
2759 case 'M':
2760 if ( !wasprefixed )
2761 {
2762 if ( e->ac < 2 || do_parse_number(e, e->av[1], &numval) )
2763 break;
2764 *(u16 *)((char *)cnfdata + options->m_offset) = (u16)numval;
2765 }
2766 if ( !strcmp("want.mru", (const char *)e->av[0]) )
2767 *((u8 *)cnfdata + 169) = !wasprefixed;
2768 else
2769 *((u8 *)cnfdata + 245) = !wasprefixed;
2770 return 0;
2771 case 'P':
2772 numval = 0xFFFFFFFF;
2773 if ( !wasprefixed )
2774 {
2775 if ( e->ac < 2 )
2776 break;
2777 if ( !strcmp("auto", (const char *)e->av[1]) )
2778 {
2779 numval = 1;
2780 }
2781 else if ( !strcmp("10", (const char *)e->av[1]) )
2782 {
2783 numval = 2;
2784 }
2785 else if ( !strcmp("10_fd", (const char *)e->av[1]) )
2786 {
2787 numval = 3;
2788 }
2789 else if ( !strcmp("10_fd_pause", (const char *)e->av[1]) )
2790 {
2791 numval = 4;
2792 }
2793 else if ( !strcmp("tx", (const char *)e->av[1]) )
2794 {
2795 numval = 5;
2796 }
2797 else if ( !strcmp("tx_fd", (const char *)e->av[1]) )
2798 {
2799 numval = 6;
2800 }
2801 else if ( !strcmp("tx_fd_pause", (const char *)e->av[1]) )
2802 {
2803 numval = 7;
2804 }
2805 else if ( do_parse_number(e, e->av[1], &numval) )
2806 {
2807 return -1;
2808 }
2809 }
2810 *(u32 *)((char *)cnfdata + options->m_offset) = numval;
2811 return 0;
2812 case 'T':
2813 numval = 0xFFFFFFFF;
2814 if ( !wasprefixed )
2815 {
2816 if ( e->ac < 2 )
2817 break;
2818 if ( !strcmp("any", (const char *)e->av[1]) )
2819 {
2820 numval = 0;
2821 }
2822 if ( !strcmp("eth", (const char *)e->av[1]) )
2823 {
2824 numval = 1;
2825 }
2826 else if ( !strcmp("ppp", (const char *)e->av[1]) )
2827 {
2828 numval = 2;
2829 }
2830 else if ( !strcmp("nic", (const char *)e->av[1]) )
2831 {
2832 numval = 3;
2833 }
2834 else if ( do_parse_number(e, e->av[1], &numval) )
2835 {
2836 return -1;
2837 }
2838 }
2839 *(u32 *)((char *)cnfdata + options->m_offset) = numval;
2840 return 0;
2841 case 'b':
2842 numval = !wasprefixed;
2843 *((u8 *)cnfdata + options->m_offset) = (u8)numval;
2844 return 0;
2845 case 'c':
2846 numval = 255;
2847 if ( !wasprefixed )
2848 {
2849 if ( e->ac < 2 )
2850 break;
2851 if ( !strcmp("no", (const char *)e->av[1]) )
2852 {
2853 numval = 0;
2854 }
2855 else if ( !strcmp("md5", (const char *)e->av[1]) )
2856 {
2857 numval = 5;
2858 }
2859 else if ( !strcmp("ms", (const char *)e->av[1]) )
2860 {
2861 numval = 128;
2862 }
2863 else if ( !strcmp("ms-v1", (const char *)e->av[1]) )
2864 {
2865 numval = 128;
2866 }
2867 else if ( !strcmp("ms-v2", (const char *)e->av[1]) )
2868 {
2869 numval = 129;
2870 }
2871 else if ( do_parse_number(e, e->av[1], &numval) )
2872 {
2873 return -1;
2874 }
2875 }
2876 *((u8 *)cnfdata + options->m_offset) = (u8)numval;
2877 return 0;
2878 case 'p':
2879 if ( !wasprefixed )
2880 {
2881 if ( e->ac < 2 )
2882 {
2883 break;
2884 }
2885 *(char **)((char *)cnfdata + options->m_offset) = do_check_e_arg(e, e->av[1]);
2886 return (!*(char **)((char *)cnfdata + options->m_offset)) ? -1 : 0;
2887 }
2888 *(u32 *)((char *)cnfdata + options->m_offset) = 0;
2889 return 0;
2890 default:
2891 return printf("netcnf: internal load err (%d, type=%c)\n", 606, options->m_type);
2892 }
2893 }
2894 printf("netcnf: \"%s\" line %d: ", e->fname, e->lno);
2895 printf("ac=%d", e->ac);
2896 printf("\n");
2897 e->syntax_err += 1;
2898 return -1;
2899}
2900
2901static int do_handle_net_cnf(sceNetCnfEnv_t *e, void *userdata)
2902{
2903 int wasprefixed;
2904
2905 (void)userdata;
2906 wasprefixed = (e->av[0][0] == '-') ? 1 : 0;
2907 if ( strcmp("interface", &(e->av[0])[wasprefixed]) )
2908 {
2909 if ( strcmp("zero_prefix", &(e->av[0])[wasprefixed]) )
2910 return do_check_other_keywords(e, g_options_net_cnf, e->root, &e->root->unknown_list);
2911 printf("netcnf: \"%s\" line %d: ", e->fname, e->lno);
2912 printf("obsoleted keyword (%s)", &(e->av[0])[wasprefixed]);
2913 printf("\n");
2914 e->syntax_err += 1;
2915 return 0;
2916 }
2917 if ( wasprefixed )
2918 return 0;
2919 if ( e->ac < 3 )
2920 {
2921 printf("netcnf: \"%s\" line %d: ", e->fname, e->lno);
2922 printf("ac=%d", e->ac);
2923 printf("\n");
2924 e->syntax_err += 1;
2925 return -1;
2926 }
2927 return !do_check_interface_keyword(e, e->av[1], e->av[2], (e->ac >= 4) ? e->av[3] : 0) ? 0 : -1;
2928}
2929
2930static int do_handle_attach_cnf(sceNetCnfEnv_t *e, void *userdata)
2931{
2932 int wasprefixed;
2933 struct sceNetCnfInterface *ifc;
2934
2935 ifc = (struct sceNetCnfInterface *)userdata;
2936 wasprefixed = (e->av[0][0] == '-') ? 1 : 0;
2937 if ( !strncmp("phone_number", &(e->av[0])[wasprefixed], 12) )
2938 {
2939 int keyasnum;
2940
2941 keyasnum = 0;
2942 if ( e->av[0][wasprefixed + 12] )
2943 {
2944 if ( !isdigit(e->av[0][wasprefixed + 12]) || e->av[0][wasprefixed + 13] )
2945 return 0;
2946 keyasnum = e->av[0][wasprefixed + 12] - 48;
2947 }
2948 if ( wasprefixed )
2949 {
2950 ifc->phone_numbers[keyasnum] = 0;
2951 return 0;
2952 }
2953 if ( e->ac >= 2 )
2954 {
2955 ifc->phone_numbers[keyasnum] = (u8 *)do_check_e_arg(e, e->av[1]);
2956 return (ifc->phone_numbers[keyasnum]) ? 0 : -1;
2957 }
2958 }
2959 else if ( !strcmp("nameserver", &(e->av[0])[wasprefixed]) )
2960 {
2961 if ( !wasprefixed )
2962 return do_check_nameserver(e, ifc, e->ac, &e->av[0]);
2963 }
2964 else if ( !strcmp("route", &(e->av[0])[wasprefixed]) )
2965 {
2966 if ( !wasprefixed )
2967 return do_check_route(e, ifc, e->ac, &e->av[0]);
2968 }
2969 else if ( !strcmp("zero_prefix", &(e->av[0])[wasprefixed]) || !strcmp("dial_cnf", &(e->av[0])[wasprefixed]) )
2970 {
2971 printf("netcnf: \"%s\" line %d: ", e->fname, e->lno);
2972 printf("obsoleted keyword (%s)", &(e->av[0])[wasprefixed]);
2973 printf("\n");
2974 e->syntax_err += 1;
2975 }
2976 else
2977 {
2978 return do_check_other_keywords(e, g_options_attach_cnf, ifc, &ifc->unknown_list);
2979 }
2980 return 0;
2981}
2982
2983static int do_handle_dial_cnf(sceNetCnfEnv_t *e, void *userdata)
2984{
2985 int wasprefixed;
2986 struct sceNetCnfDial *dial;
2987
2988 dial = (struct sceNetCnfDial *)userdata;
2989 wasprefixed = (e->av[0][0] == '-') ? 1 : 0;
2990 if ( strcmp("dialing_type_string", &(e->av[0])[wasprefixed]) )
2991 return do_check_other_keywords(e, g_options_dial_cnf, dial, &dial->unknown_list);
2992 if ( wasprefixed || e->ac < 2 )
2993 return 0;
2994 dial->tone_dial = (u8 *)do_check_e_arg(e, e->av[1]);
2995 if ( !dial->tone_dial )
2996 return -1;
2997 if ( e->ac < 3 )
2998 return 0;
2999 dial->pulse_dial = (u8 *)do_check_e_arg(e, e->av[2]);
3000 if ( !dial->pulse_dial )
3001 return -1;
3002 if ( e->ac < 4 )
3003 return 0;
3004 dial->any_dial = (u8 *)do_check_e_arg(e, e->av[3]);
3005 return dial->any_dial ? 0 : -1;
3006}
3007
3008static int
3009do_check_line_buffer(sceNetCnfEnv_t *e, u8 *lbuf, int (*readcb)(sceNetCnfEnv_t *e, void *userdata), void *userdata)
3010{
3011 u8 *i;
3012 char *j;
3013
3014 for ( i = lbuf; e->lbuf < i && i[-1] < 0x21u; i -= 1 )
3015 ;
3016 *i = 0;
3017 for ( j = (char *)e->lbuf; *j && isspace(*j); j += 1 )
3018 ;
3019 e->ac = 0;
3020 while ( *j && e->ac < '\n' && (u8)*j != '#' )
3021 {
3022 u32 condtmp1;
3023
3024 e->av[e->ac] = j;
3025 condtmp1 = 0;
3026 if ( *j == '#' )
3027 {
3028 *j = 0;
3029 break;
3030 }
3031 if ( !isspace(*j) )
3032 {
3033 while ( *j )
3034 {
3035 if ( *j == '\\' )
3036 {
3037 if ( j[1] )
3038 j += 1;
3039 }
3040 else
3041 {
3042 condtmp1 = (*j == '"') ? (condtmp1 ? 0 : 1) : (condtmp1 ? 1 : 0);
3043 }
3044 j += 1;
3045 if ( !condtmp1 && (*j == '#' || isspace(*j)) )
3046 {
3047 break;
3048 }
3049 }
3050 }
3051 if ( *j == '#' )
3052 {
3053 *j = 0;
3054 break;
3055 }
3056 if ( *j )
3057 {
3058 *j = 0;
3059 j += 1;
3060 }
3061 for ( ; *j && isspace(*j); j += 1 )
3062 ;
3063 e->ac += 1;
3064 }
3065 *j = 0;
3066 return (e->ac <= 0) ? 0 : readcb(e, userdata);
3067}
3068
3069static int do_read_netcnf(sceNetCnfEnv_t *e, const char *netcnf_path, char **netcnf_heap_ptr, int is_attach_cnf)
3070{
3071 int result;
3072
3073 result = (!is_attach_cnf || e->f_no_decode) ? do_read_netcnf_no_decode(netcnf_path, netcnf_heap_ptr) :
3074 do_read_netcnf_decode(netcnf_path, netcnf_heap_ptr);
3075 if ( result < 0 )
3076 e->file_err += 1;
3077 return result;
3078}
3079
3080static const char *do_handle_netcnf_prerw(sceNetCnfEnv_t *e, const char *entry_buffer)
3081{
3082 const char *result;
3083
3084 result = do_handle_netcnf_dirname(e->dir_name, entry_buffer, (char *)e->lbuf);
3085 return (result == (const char *)e->lbuf) ? do_alloc_mem_for_write(e, result) : result;
3086}
3087
3088static int do_netcnf_read_related(
3089 sceNetCnfEnv_t *e, const char *path, int (*readcb)(sceNetCnfEnv_t *e, void *userdata), void *userdata)
3090{
3091 int cur_linelen;
3092 const char *fullpath;
3093 int read_res1;
3094 u8 *lbuf;
3095 char *ptr;
3096 int i;
3097
3098 cur_linelen = 0;
3099 if ( e->f_verbose )
3100 printf("netcnf: dir=%s path=%s\n", e->dir_name ? e->dir_name : "NULL", path ? path : "NULL");
3101 fullpath = do_handle_netcnf_prerw(e, path);
3102 if ( !fullpath )
3103 return -1;
3104 if ( e->f_verbose )
3105 {
3106 printf("netcnf: reading \"%s\" as ", fullpath);
3107 if ( (char *)readcb == (char *)do_handle_net_cnf )
3108 {
3109 printf("NET_CNF");
3110 }
3111 else if ( (char *)readcb == (char *)do_handle_attach_cnf )
3112 {
3113 printf("ATTACH_CNF");
3114 }
3115 else if ( (char *)readcb == (char *)do_handle_dial_cnf )
3116 {
3117 printf("DIAL_CNF");
3118 }
3119 else
3120 {
3121 printf("???");
3122 }
3123 printf("\n");
3124 }
3125 e->fname = fullpath;
3126 read_res1 = do_read_netcnf(e, fullpath, &ptr, readcb == do_handle_attach_cnf);
3127 if ( read_res1 < 0 )
3128 {
3129 printf("netcnf: can't load %s (%d)\n", e->fname, read_res1);
3130 return -1;
3131 }
3132 e->lno = 0;
3133 if ( !e->f_no_check_magic && (read_res1 < 36 || strncmp(ptr, "# <Sony Computer Entertainment Inc.>", 36)) )
3134 {
3135 printf("netcnf: decoding error (magic=\"");
3136 for ( i = 0; i < read_res1 && i < 36; i += 1 )
3137 {
3138 printf("%c", ((u8)ptr[i] - (unsigned int)' ' < '_') ? ((u8)ptr[i]) : '?');
3139 }
3140 printf("\")\n");
3141 do_free_heapmem(ptr);
3142 return -15;
3143 }
3144 lbuf = e->lbuf;
3145 for ( i = 0; i < read_res1; i += 1 )
3146 {
3147 if ( ptr[i] == '\n' )
3148 {
3149 e->lno += 1;
3150 if ( e->lbuf < lbuf && lbuf[-1] == '\\' )
3151 {
3152 lbuf -= 1;
3153 }
3154 else
3155 {
3156 cur_linelen += do_check_line_buffer(e, lbuf, readcb, userdata);
3157 lbuf = e->lbuf;
3158 }
3159 }
3160 else
3161 {
3162 if ( lbuf < &e->lbuf[1023] && ptr[i] != '\r' )
3163 {
3164 *lbuf = (u8)ptr[i];
3165 lbuf += 1;
3166 }
3167 }
3168 }
3169 if ( e->lbuf < lbuf )
3170 cur_linelen += do_check_line_buffer(e, lbuf, readcb, userdata);
3171 do_free_heapmem(ptr);
3172 return cur_linelen;
3173}
3174
3175static int do_netcnf_dial_related(sceNetCnfEnv_t *e)
3176{
3177 e->root = (sceNetCnfRoot_t *)do_alloc_mem_inner(e, sizeof(sceNetCnfRoot_t), 2);
3178 if ( !e->root )
3179 return -2;
3180 e->root->version = 3;
3181 e->root->redial_count = -1;
3182 e->root->redial_interval = -1;
3183 e->root->dialing_type = -1;
3184 return do_netcnf_read_related(e, e->arg_fname, do_handle_net_cnf, 0);
3185}
3186
3187static int do_netcnf_ifc_related(sceNetCnfEnv_t *e)
3188{
3189 e->ifc = (sceNetCnfInterface_t *)do_alloc_mem_inner(e, sizeof(sceNetCnfInterface_t), 2);
3190 if ( !e->ifc )
3191 return -2;
3192 do_init_ifc_inner(e->ifc);
3193 return do_netcnf_read_related(e, e->arg_fname, do_handle_attach_cnf, e->ifc);
3194}
3195
3196static void do_dialauth_related(sceNetCnfInterface_t *ncid, struct sceNetCnfInterface *ncis)
3197{
3198 int i;
3199 u32 typadd1_1;
3200 u32 typadd1_3;
3201 u8 typadd1;
3202
3203 if ( !ncis )
3204 {
3205 return;
3206 }
3207 for ( i = 0; g_options_attach_cnf[i].m_key; i += 1 )
3208 {
3209 switch ( g_options_attach_cnf[i].m_type )
3210 {
3211 case '1':
3212 case 'b':
3213 case 'c':
3214 typadd1 = *((u8 *)&ncis->type + g_options_attach_cnf[i].m_offset);
3215 if ( typadd1 != 0xFF )
3216 *((u8 *)&ncid->type + g_options_attach_cnf[i].m_offset) = typadd1;
3217 break;
3218 case '4':
3219 case 'D':
3220 case 'L':
3221 case 'P':
3222 case 'T':
3223 typadd1_1 = *(u32 *)((char *)&ncis->type + g_options_attach_cnf[i].m_offset);
3224 if ( typadd1_1 != 0xFFFFFFFF )
3225 *(u32 *)((char *)&ncid->type + g_options_attach_cnf[i].m_offset) = typadd1_1;
3226 break;
3227 case 'A':
3228 if ( !strcmp("want.auth", g_options_attach_cnf[i].m_key) )
3229 {
3230 if ( ncis->want.f_auth )
3231 {
3232 ncid->want.f_auth = 1;
3233 ncid->want.auth = ncis->want.auth;
3234 }
3235 }
3236 else if ( ncis->allow.f_auth )
3237 {
3238 ncid->allow.f_auth = 1;
3239 ncid->allow.auth = ncis->allow.auth;
3240 }
3241 break;
3242 case 'C':
3243 if ( !strcmp("want.accm", g_options_attach_cnf[i].m_key) )
3244 {
3245 if ( ncis->want.f_accm )
3246 {
3247 ncid->want.f_accm = 1;
3248 ncid->want.accm = ncis->want.accm;
3249 }
3250 }
3251 else if ( ncis->allow.f_accm )
3252 {
3253 ncid->allow.f_accm = 1;
3254 ncid->allow.accm = ncis->allow.accm;
3255 }
3256 break;
3257 case 'M':
3258 if ( !strcmp("want.mru", g_options_attach_cnf[i].m_key) )
3259 {
3260 if ( ncis->want.f_mru )
3261 {
3262 ncid->want.f_mru = 1;
3263 ncid->want.mru = ncis->want.mru;
3264 }
3265 }
3266 else if ( ncis->allow.f_mru )
3267 {
3268 ncid->allow.f_mru = 1;
3269 ncid->allow.mru = ncis->allow.mru;
3270 }
3271 break;
3272 case 'p':
3273 typadd1_3 = *(u32 *)((char *)&ncis->type + g_options_attach_cnf[i].m_offset);
3274 if ( typadd1_3 )
3275 *(u32 *)((char *)&ncid->type + g_options_attach_cnf[i].m_offset) = typadd1_3;
3276 break;
3277 default:
3278 break;
3279 }
3280 }
3281 for ( i = 0; i < 10; i += 1 )
3282 {
3283 if ( ncis->phone_numbers[i] )
3284 ncid->phone_numbers[i] = ncis->phone_numbers[i];
3285 }
3286}
3287
3288static int do_merge_conf_inner(sceNetCnfEnv_t *e)
3289{
3290 struct sceNetCnfPair *pair_head;
3291
3292 if ( !e->root )
3293 {
3294 return -1;
3295 }
3296 for ( pair_head = e->root->pair_head; pair_head; pair_head = pair_head->forw )
3297 {
3298 int type;
3299
3300 if ( !pair_head->ctl )
3301 {
3302 pair_head->ctl = (sceNetCnfCtl_t *)do_alloc_mem_inner(e, sizeof(sceNetCnfCtl_t), 2);
3303 if ( !pair_head->ctl )
3304 return -2;
3305 }
3306 if ( !pair_head->ctl->dial )
3307 {
3308 pair_head->ctl->dial = (sceNetCnfDial_t *)do_alloc_mem_inner(e, sizeof(sceNetCnfDial_t), 2);
3309 if ( !pair_head->ctl->dial )
3310 return -2;
3311 }
3312 if ( !pair_head->ctl->ifc )
3313 {
3314 pair_head->ctl->ifc = (sceNetCnfInterface_t *)do_alloc_mem_inner(e, sizeof(sceNetCnfInterface_t), 2);
3315 if ( !pair_head->ctl->ifc )
3316 return -2;
3317 }
3318 do_init_ifc_inner(pair_head->ctl->ifc);
3319 pair_head->ctl->ifc->chat_additional = e->root->chat_additional;
3320 pair_head->ctl->ifc->redial_count = e->root->redial_count;
3321 pair_head->ctl->ifc->redial_interval = e->root->redial_interval;
3322 pair_head->ctl->ifc->outside_number = e->root->outside_number;
3323 pair_head->ctl->ifc->outside_delay = e->root->outside_delay;
3324 pair_head->ctl->ifc->dialing_type = e->root->dialing_type;
3325 do_dialauth_related(pair_head->ctl->ifc, pair_head->ifc);
3326 type = pair_head->dev->type;
3327 pair_head->dev->type = -1;
3328 do_dialauth_related(pair_head->ctl->ifc, pair_head->dev);
3329 pair_head->dev->type = type;
3330 }
3331 return 0;
3332}
3333
3334static int do_load_conf_inner(sceNetCnfEnv_t *e)
3335{
3336 int retres1;
3337 struct sceNetCnfPair *pair_head;
3338
3339 retres1 = 0;
3340 switch ( e->req )
3341 {
3342 case 1:
3343 {
3344 int ifcres1_1;
3345
3346 ifcres1_1 = do_netcnf_dial_related(e);
3347 if ( ifcres1_1 )
3348 return ifcres1_1;
3349 if ( !e->root )
3350 return -14;
3351 pair_head = e->root->pair_head;
3352 if ( !pair_head )
3353 return -14;
3354 if ( index(e->arg_fname, ':') )
3355 e->dir_name = e->arg_fname;
3356 for ( ; pair_head; pair_head = pair_head->forw )
3357 {
3358 if ( pair_head->attach_ifc )
3359 {
3360 e->arg_fname = (char *)pair_head->attach_ifc;
3361 ifcres1_1 = do_netcnf_ifc_related(e);
3362 if ( ifcres1_1 )
3363 {
3364 printf("netcnf: load_attach ifc(%d)\n", ifcres1_1);
3365 pair_head->ifc = 0;
3366 if ( (unsigned int)(ifcres1_1 + 15) < 2 )
3367 {
3368 pair_head->dev = 0;
3369 break;
3370 }
3371 retres1 = -21;
3372 }
3373 else
3374 {
3375 pair_head->ifc = e->ifc;
3376 }
3377 }
3378 else
3379 {
3380 pair_head->ifc = 0;
3381 }
3382 if ( pair_head->attach_dev )
3383 {
3384 e->arg_fname = (char *)pair_head->attach_dev;
3385 ifcres1_1 = do_netcnf_ifc_related(e);
3386 if ( ifcres1_1 )
3387 {
3388 printf("netcnf: load_attach dev(%d)\n", ifcres1_1);
3389 pair_head->dev = 0;
3390 if ( (unsigned int)(ifcres1_1 + 15) < 2 )
3391 break;
3392 retres1 = -21;
3393 }
3394 else
3395 {
3396 pair_head->dev = e->ifc;
3397 }
3398 }
3399 else
3400 {
3401 pair_head->dev = 0;
3402 }
3403 }
3404 return (retres1 == -21) ? -21 : ifcres1_1;
3405 }
3406 case 2:
3407 return do_netcnf_ifc_related(e);
3408 default:
3409 return -1;
3410 }
3411}
3412
3413static int do_load_dial_inner(sceNetCnfEnv_t *e, sceNetCnfPair_t *pair)
3414{
3415 if ( !pair->ctl )
3416 return -1;
3417 pair->ctl->dial = (sceNetCnfDial_t *)do_alloc_mem_inner(e, sizeof(sceNetCnfDial_t), 2);
3418 return pair->ctl->dial ? do_netcnf_read_related(e, e->arg_fname, do_handle_dial_cnf, pair->ctl->dial) : -2;
3419}
3420
3421static int do_netcnf_vsprintf_buffer(sceNetCnfEnv_t *e, const char *fmt, va_list va)
3422{
3423 char *mem_ptr_03;
3424 void *mem_ptr_rval_04;
3425 int has_negative;
3426 char has_sero;
3427 int strlened;
3428 int fmt_flag_str;
3429 char *mem_ptr_01;
3430 char *strptr1;
3431 int strlenmax;
3432 int strpad1;
3433 int cur_va1;
3434 int strlencalc;
3435 char *mem_ptr_02;
3436 char *mem_ptr_04;
3437 char *mem_ptr_05;
3438 char *i;
3439 char *mem_ptr_0a;
3440 void *mem_ptr_rval_02;
3441 char i_curchr2;
3442 void *mem_ptr_rval_03;
3443 char *mem_ptr_07;
3444 char *mem_ptr_09;
3445 void *mem_ptr_rval_01;
3446 char *mem_ptr_08;
3447 char strptr_curchr1;
3448 char *mem_ptr_06;
3449
3450 strptr1 = 0;
3451 strlenmax = 0;
3452 while ( *fmt )
3453 {
3454 if ( *fmt == '%' )
3455 {
3456 fmt += 1;
3457 has_negative = 0;
3458 if ( *fmt == '-' )
3459 {
3460 fmt += 1;
3461 has_negative = 1;
3462 }
3463 has_sero = ' ';
3464 if ( *fmt == '0' )
3465 {
3466 has_sero = '0';
3467 fmt += 1;
3468 }
3469 strlened = 0;
3470 for ( ; isdigit(*fmt); fmt += 1 )
3471 {
3472 strlened = 10 * strlened - '0' + *fmt;
3473 }
3474 if ( *fmt == 'l' )
3475 fmt += 1;
3476 fmt_flag_str = -1;
3477 strpad1 = 0;
3478 switch ( *fmt )
3479 {
3480 case 'c':
3481 mem_ptr_01 = (char *)e->mem_ptr;
3482 mem_ptr_rval_04 = mem_ptr_01 + 1;
3483 if ( mem_ptr_01 >= (char *)e->mem_last )
3484 return -2;
3485 *mem_ptr_01 = (char)va_arg(va, int);
3486 e->mem_ptr = mem_ptr_rval_04;
3487 fmt += 1;
3488 continue;
3489 case 'p':
3490 has_sero = '0';
3491 if ( strlened < 8 )
3492 strlened = 8;
3493 strpad1 = 16;
3494 break;
3495 case 'X':
3496 case 'x':
3497 strpad1 = 16;
3498 break;
3499 case 'd':
3500 case 'u':
3501 strpad1 = 10;
3502 break;
3503 case 'o':
3504 strpad1 = 8;
3505 break;
3506 case 'S':
3507 fmt_flag_str = 1;
3508 break;
3509 case 's':
3510 fmt_flag_str = 0;
3511 break;
3512 default:
3513 mem_ptr_03 = (char *)e->mem_ptr;
3514 mem_ptr_rval_04 = mem_ptr_03 + 1;
3515 if ( mem_ptr_03 >= (char *)e->mem_last )
3516 return -2;
3517 *mem_ptr_03 = *fmt;
3518 e->mem_ptr = mem_ptr_rval_04;
3519 fmt += 1;
3520 continue;
3521 }
3522 if ( fmt_flag_str != -1 )
3523 {
3524 strptr1 = va_arg(va, char *);
3525 strlenmax = 0;
3526 if ( !strptr1 )
3527 strpad1 = 0;
3528 }
3529 if ( strpad1 )
3530 {
3531 cur_va1 = va_arg(va, int);
3532 strptr1 = __builtin_alloca(strpad1 + 1);
3533 strptr1[strpad1] = 0;
3534 strptr1 += strpad1;
3535 strlenmax = 0;
3536 if ( *fmt == 'd' && cur_va1 < 0 )
3537 {
3538 cur_va1 = -cur_va1;
3539 strlenmax = 1;
3540 }
3541 while ( 1 )
3542 {
3543 strptr1 -= 1;
3544 *strptr1 = ((*fmt == 'X') ? "0123456789ABCDEF" : "0123456789abcdef")[cur_va1 % strpad1];
3545 cur_va1 /= strpad1;
3546 if ( !cur_va1 )
3547 break;
3548 }
3549 }
3550 if ( strptr1 )
3551 {
3552 strlencalc = strlenmax ? (strlened + 1) : strlened;
3553 strlencalc -= strlen(strptr1);
3554 if ( has_sero == '0' && strlenmax )
3555 {
3556 mem_ptr_02 = (char *)e->mem_ptr;
3557 if ( mem_ptr_02 >= (char *)e->mem_last )
3558 return -2;
3559 *mem_ptr_02 = '-';
3560 e->mem_ptr = mem_ptr_02 + 1;
3561 }
3562 if ( !has_negative )
3563 {
3564 for ( ; strlencalc > 0; strlencalc -= 1 )
3565 {
3566 mem_ptr_04 = (char *)e->mem_ptr;
3567 if ( mem_ptr_04 >= (char *)e->mem_last )
3568 return -2;
3569 *mem_ptr_04 = has_sero;
3570 e->mem_ptr = mem_ptr_04 + 1;
3571 }
3572 }
3573 if ( has_sero != '0' && strlenmax )
3574 {
3575 mem_ptr_05 = (char *)e->mem_ptr;
3576 if ( mem_ptr_05 >= (char *)e->mem_last )
3577 return -2;
3578 *mem_ptr_05 = '-';
3579 e->mem_ptr = mem_ptr_05 + 1;
3580 }
3581 if ( fmt_flag_str != 1 )
3582 {
3583 for ( ; *strptr1; strptr1 += 1 )
3584 {
3585 strptr_curchr1 = *strptr1;
3586 mem_ptr_06 = (char *)e->mem_ptr;
3587 if ( mem_ptr_06 >= (char *)e->mem_last )
3588 return -2;
3589 *mem_ptr_06 = strptr_curchr1;
3590 e->mem_ptr = mem_ptr_06 + 1;
3591 }
3592 }
3593 else
3594 {
3595 for ( i = strptr1; *i; i += 1 )
3596 {
3597 if (
3598 (((u8)*i - 0x81 >= 0x1F) && ((u8)*i - 0xE0 >= 0x1D)) || ((u8)((int)*i - 64) >= 0xBDu) || (u8)*i == 0x7F )
3599 {
3600 if ( (u8)*i == '"' || (u8)*i == '\\' )
3601 {
3602 mem_ptr_07 = (char *)e->mem_ptr;
3603 if ( mem_ptr_07 >= (char *)e->mem_last )
3604 return -2;
3605 *mem_ptr_07 = '\\';
3606 e->mem_ptr = mem_ptr_07 + 1;
3607 mem_ptr_rval_03 = mem_ptr_07 + 2;
3608 if ( mem_ptr_07 + 1 >= (char *)e->mem_last )
3609 return -2;
3610 mem_ptr_07[1] = *i;
3611 }
3612 else if ( (u8)*i - ' ' < '_' )
3613 {
3614 mem_ptr_08 = (char *)e->mem_ptr;
3615 mem_ptr_rval_03 = mem_ptr_08 + 1;
3616 if ( mem_ptr_08 >= (char *)e->mem_last )
3617 return -2;
3618 *mem_ptr_08 = *i;
3619 }
3620 else
3621 {
3622 mem_ptr_09 = (char *)e->mem_ptr;
3623 if ( mem_ptr_09 >= (char *)e->mem_last )
3624 return -2;
3625 *mem_ptr_09 = '\\';
3626 e->mem_ptr = mem_ptr_09 + 1;
3627 if ( mem_ptr_09 + 1 >= (char *)e->mem_last )
3628 return -2;
3629 mem_ptr_09[1] = 'x';
3630 e->mem_ptr = mem_ptr_09 + 2;
3631 mem_ptr_rval_01 = mem_ptr_09 + 3;
3632 if ( mem_ptr_09 + 2 >= (char *)e->mem_last )
3633 return -2;
3634 mem_ptr_09[2] = ("0123456789abcdef")[(u8)*i >> 4];
3635 e->mem_ptr = mem_ptr_rval_01;
3636 mem_ptr_rval_03 = mem_ptr_09 + 4;
3637 if ( (char *)mem_ptr_rval_01 >= (char *)e->mem_last )
3638 return -2;
3639 mem_ptr_09[3] = ("0123456789abcdef")[(u8)*i & 0xF];
3640 }
3641 }
3642 else
3643 {
3644 mem_ptr_0a = (char *)e->mem_ptr;
3645 mem_ptr_rval_02 = mem_ptr_0a + 1;
3646 if ( mem_ptr_0a >= (char *)e->mem_last )
3647 return -2;
3648 *mem_ptr_0a = *i;
3649 e->mem_ptr = mem_ptr_rval_02;
3650 i_curchr2 = *i;
3651 i += 1;
3652 if ( (char *)mem_ptr_rval_02 >= (char *)e->mem_last )
3653 return -2;
3654 mem_ptr_rval_03 = mem_ptr_0a + 2;
3655 mem_ptr_0a[1] = i_curchr2;
3656 }
3657 e->mem_ptr = mem_ptr_rval_03;
3658 }
3659 }
3660 for ( ; has_negative && strlencalc > 0; strlencalc -= 1 )
3661 {
3662 if ( (char *)e->mem_ptr >= (char *)e->mem_last )
3663 return -2;
3664 *((char *)e->mem_ptr) = ' ';
3665 e->mem_ptr = ((char *)e->mem_ptr) + 1;
3666 }
3667 }
3668 }
3669 else
3670 {
3671 mem_ptr_03 = (char *)e->mem_ptr;
3672 mem_ptr_rval_04 = mem_ptr_03 + 1;
3673 if ( mem_ptr_03 >= (char *)e->mem_last )
3674 return -2;
3675 *mem_ptr_03 = *fmt;
3676 e->mem_ptr = mem_ptr_rval_04;
3677 }
3678 fmt += 1;
3679 }
3680 return 0;
3681}
3682
3683static int do_netcnf_sprintf_buffer(sceNetCnfEnv_t *e, const char *fmt, ...)
3684{
3685 va_list va;
3686 int retval;
3687
3688 va_start(va, fmt);
3689 retval = do_netcnf_vsprintf_buffer(e, fmt, va);
3690 va_end(va);
3691 return retval;
3692}
3693
3694static int do_netcnf_other_write(sceNetCnfEnv_t *e, const struct netcnf_option *options, void *cnfdata)
3695{
3696 char *offsptr1;
3697 unsigned int offsptr6;
3698 unsigned int offsptr4;
3699 int i;
3700
3701 for ( ; options->m_key; options += 1 )
3702 {
3703 unsigned int offsptr3;
3704 int result;
3705 const char *lbuf;
3706
3707 offsptr3 = 0;
3708 result = 0;
3709 lbuf = (const char *)e->lbuf;
3710 switch ( options->m_type )
3711 {
3712 case '1':
3713 if ( *((u8 *)cnfdata + options->m_offset) == 255 )
3714 {
3715 lbuf = 0;
3716 break;
3717 }
3718 result = do_netcnf_sprintf_buffer(e, "%s %d\n", options->m_key, *((u8 *)cnfdata + options->m_offset));
3719 lbuf = 0;
3720 break;
3721 case '4':
3722 offsptr1 = (char *)cnfdata + options->m_offset;
3723 if ( *(int *)offsptr1 < 0 )
3724 {
3725 lbuf = 0;
3726 break;
3727 }
3728 result = do_netcnf_sprintf_buffer(e, "%s %d\n", options->m_key, *(u32 *)offsptr1);
3729 lbuf = 0;
3730 break;
3731 case 'A':
3732 if ( !strcmp("want.auth", options->m_key) ? !*((u8 *)cnfdata + 171) : !*((u8 *)cnfdata + 247) )
3733 {
3734 lbuf = 0;
3735 break;
3736 }
3737 offsptr3 = (u32)(s32) * ((char *)cnfdata + options->m_offset);
3738 switch ( offsptr3 )
3739 {
3740 case 0:
3741 lbuf = "any";
3742 break;
3743 case 1:
3744 lbuf = "pap";
3745 break;
3746 case 2:
3747 lbuf = "chap";
3748 break;
3749 case 3:
3750 lbuf = "pap/chap";
3751 break;
3752 case 4:
3753 lbuf = "chap/pap";
3754 break;
3755 default:
3756 break;
3757 }
3758 break;
3759 case 'C':
3760 if ( !strcmp("want.accm", options->m_key) ? !*((u8 *)cnfdata + 170) : !*((u8 *)cnfdata + 246) )
3761 {
3762 lbuf = 0;
3763 break;
3764 }
3765 result =
3766 do_netcnf_sprintf_buffer(e, "%s 0x%08x\n", options->m_key, *(u32 *)((char *)cnfdata + options->m_offset));
3767 lbuf = 0;
3768 break;
3769 case 'D':
3770 offsptr3 = *(u32 *)((char *)cnfdata + options->m_offset);
3771 switch ( offsptr3 )
3772 {
3773 case 0xFFFFFFFF:
3774 lbuf = 0;
3775 break;
3776 case 0:
3777 lbuf = "tone";
3778 break;
3779 case 1:
3780 lbuf = "pulse";
3781 break;
3782 case 2:
3783 lbuf = "any";
3784 break;
3785 default:
3786 break;
3787 }
3788 break;
3789 case 'L':
3790 offsptr4 = *(u32 *)((char *)cnfdata + options->m_offset);
3791 if ( offsptr4 == 0xFFFFFFFF )
3792 {
3793 lbuf = 0;
3794 break;
3795 }
3796 result = do_netcnf_sprintf_buffer(e, "%s", options->m_key);
3797 if ( result < 0 )
3798 return result;
3799 for ( i = 0; i < 32; i += 1 )
3800 {
3801 lbuf = 0;
3802 switch ( ((u32)1 << i) & offsptr4 )
3803 {
3804 case 1u:
3805 lbuf = "phase";
3806 break;
3807 case 2u:
3808 lbuf = "cp";
3809 break;
3810 case 4u:
3811 lbuf = "auth";
3812 break;
3813 case 8u:
3814 lbuf = "chat";
3815 break;
3816 case 0x10u:
3817 lbuf = "private";
3818 break;
3819 case 0x20u:
3820 lbuf = "dll";
3821 break;
3822 case 0x40u:
3823 lbuf = "dump";
3824 break;
3825 case 0x10000:
3826 lbuf = "timer";
3827 break;
3828 case 0x20000:
3829 lbuf = "event";
3830 break;
3831 default:
3832 break;
3833 }
3834 if ( lbuf )
3835 {
3836 offsptr4 &= ~((u32)1 << i);
3837 result = do_netcnf_sprintf_buffer(e, " %s", lbuf);
3838 if ( result < 0 )
3839 return result;
3840 }
3841 }
3842 if ( offsptr4 )
3843 {
3844 result = do_netcnf_sprintf_buffer(e, " 0x%x", offsptr4);
3845 if ( result < 0 )
3846 return result;
3847 }
3848 result = do_netcnf_sprintf_buffer(e, "\n");
3849 lbuf = 0;
3850 break;
3851 case 'M':
3852 if ( !strcmp("want.mru", options->m_key) ? !*((u8 *)cnfdata + 169) : !*((u8 *)cnfdata + 245) )
3853 {
3854 lbuf = 0;
3855 break;
3856 }
3857 result = do_netcnf_sprintf_buffer(e, "%s %d\n", options->m_key, *(u16 *)((char *)cnfdata + options->m_offset));
3858 lbuf = 0;
3859 break;
3860 case 'P':
3861 offsptr3 = *(u32 *)((char *)cnfdata + options->m_offset);
3862 switch ( offsptr3 )
3863 {
3864 case 0xFFFFFFFF:
3865 lbuf = 0;
3866 break;
3867 case 1:
3868 lbuf = "auto";
3869 break;
3870 case 2:
3871 lbuf = "10";
3872 break;
3873 case 3:
3874 lbuf = "10_fd";
3875 break;
3876 case 4:
3877 lbuf = "10_fd_pause";
3878 break;
3879 case 5:
3880 lbuf = "tx";
3881 break;
3882 case 6:
3883 lbuf = "tx_fd";
3884 break;
3885 case 7:
3886 lbuf = "tx_fd_pause";
3887 break;
3888 default:
3889 break;
3890 }
3891 break;
3892 case 'T':
3893 offsptr3 = *(u32 *)((char *)cnfdata + options->m_offset);
3894 switch ( offsptr3 )
3895 {
3896 case 0xFFFFFFFF:
3897 lbuf = 0;
3898 break;
3899 case 0:
3900 lbuf = "any";
3901 break;
3902 case 1:
3903 lbuf = "eth";
3904 break;
3905 case 2:
3906 lbuf = "ppp";
3907 break;
3908 case 3:
3909 lbuf = "nic";
3910 break;
3911 default:
3912 break;
3913 }
3914 break;
3915 case 'b':
3916 if ( *((u8 *)cnfdata + options->m_offset) == 255 )
3917 {
3918 lbuf = 0;
3919 break;
3920 }
3921 result = do_netcnf_sprintf_buffer(e, "%s%s\n", *((u8 *)cnfdata + options->m_offset) ? "" : "-", options->m_key);
3922 lbuf = 0;
3923 break;
3924 case 'c':
3925 offsptr3 = (u32)(s32) * ((char *)cnfdata + options->m_offset);
3926 switch ( offsptr3 )
3927 {
3928 case 0xFFFFFFFF:
3929 lbuf = 0;
3930 break;
3931 case 0:
3932 lbuf = "no";
3933 break;
3934 case 5:
3935 lbuf = "md5";
3936 break;
3937 case 128:
3938 lbuf = "ms-v1";
3939 break;
3940 case 129:
3941 lbuf = "ms-v2";
3942 break;
3943 default:
3944 break;
3945 }
3946 break;
3947 case 'p':
3948 offsptr6 = *(u32 *)((char *)cnfdata + options->m_offset);
3949 if ( !offsptr6 )
3950 {
3951 lbuf = 0;
3952 break;
3953 }
3954 result = do_netcnf_sprintf_buffer(e, "%s \"%S\"\n", options->m_key, offsptr6);
3955 lbuf = 0;
3956 break;
3957 default:
3958 return printf("netcnf: internal save error (%d, type=%c)\n", 302, options->m_type);
3959 }
3960 if ( lbuf )
3961 {
3962 if ( (const char *)e->lbuf == (const char *)lbuf )
3963 {
3964 sprintf((char *)e->lbuf, "0x%x", offsptr3);
3965 }
3966 result = do_netcnf_sprintf_buffer(e, "%s %s\n", options->m_key, lbuf);
3967 }
3968 if ( result < 0 )
3969 return result;
3970 }
3971 return 0;
3972}
3973
3974static int do_netcnf_net_write(sceNetCnfEnv_t *e, struct sceNetCnfInterface *ifc)
3975{
3976 struct sceNetCnfCommand *cmd_head;
3977 int result;
3978
3979 for ( cmd_head = ifc->cmd_head; cmd_head; cmd_head = cmd_head->forw )
3980 {
3981 int nameserverflag;
3982
3983 nameserverflag = -1;
3984 switch ( cmd_head->code )
3985 {
3986 case 1:
3987 nameserverflag = 1;
3988 break;
3989 case 2:
3990 nameserverflag = 0;
3991 break;
3992 case 3:
3993 {
3994 result = do_netcnf_sprintf_buffer(e, "route add -%s", (((route_t *)cmd_head)->re.flags & 2) ? "host" : "net");
3995 if ( result < 0 )
3996 return result;
3997 if ( sceNetCnfAddress2String((char *)e->lbuf, sizeof(e->lbuf), &((route_t *)cmd_head)->re.dstaddr) )
3998 return -1;
3999 result = do_netcnf_sprintf_buffer(e, " %s", (const char *)e->lbuf);
4000 if ( result < 0 )
4001 return result;
4002 if ( (((route_t *)cmd_head)->re.flags & 4) )
4003 {
4004 if ( sceNetCnfAddress2String((char *)e->lbuf, sizeof(e->lbuf), &((route_t *)cmd_head)->re.gateway) )
4005 return -1;
4006 result = do_netcnf_sprintf_buffer(e, " gw %s", (const char *)e->lbuf);
4007 if ( result < 0 )
4008 return result;
4009 }
4010 if ( sceNetCnfAddress2String((char *)e->lbuf, sizeof(e->lbuf), &((route_t *)cmd_head)->re.genmask) )
4011 return -1;
4012 result = do_netcnf_sprintf_buffer(e, " netmask %s", (const char *)e->lbuf);
4013 if ( result < 0 )
4014 return result;
4015 result = do_netcnf_sprintf_buffer(e, "\n");
4016 if ( result < 0 )
4017 return result;
4018 break;
4019 }
4020 case 4:
4021 {
4022 if ( sceNetCnfAddress2String((char *)e->lbuf, sizeof(e->lbuf), &((route_t *)cmd_head)->re.dstaddr) )
4023 return -1;
4024 result = do_netcnf_sprintf_buffer(e, "route del %s\n", (const char *)e->lbuf);
4025 if ( result < 0 )
4026 return result;
4027 break;
4028 }
4029 default:
4030 return -1;
4031 }
4032 if ( nameserverflag != -1 )
4033 {
4034 if ( sceNetCnfAddress2String((char *)e->lbuf, sizeof(e->lbuf), &((nameserver_t *)cmd_head)->address) )
4035 return -1;
4036 result = do_netcnf_sprintf_buffer(e, "nameserver %s %s\n", nameserverflag ? "add" : "del", (const char *)e->lbuf);
4037 if ( result < 0 )
4038 return result;
4039 }
4040 }
4041 return 0;
4042}
4043
4044static int do_netcnf_phone_write(sceNetCnfEnv_t *e, struct sceNetCnfInterface *ifc)
4045{
4046 int i;
4047 int result;
4048
4049 for ( i = 0; i < (int)(sizeof(ifc->phone_numbers) / sizeof(ifc->phone_numbers[0])); i += 1 )
4050 {
4051 if ( ifc->phone_numbers[i] )
4052 {
4053 result = do_netcnf_sprintf_buffer(e, "phone_number%d \"%S\"\n", i, ifc->phone_numbers[i]);
4054 if ( result < 0 )
4055 return result;
4056 }
4057 }
4058 return 0;
4059}
4060
4061static int do_netcnf_unknown_write(sceNetCnfEnv_t *e, struct sceNetCnfUnknownList *unknown_list)
4062{
4063 struct sceNetCnfUnknown *head;
4064
4065 for ( head = unknown_list->head; head; head = head->forw )
4066 {
4067 int result;
4068
4069 result = do_netcnf_sprintf_buffer(e, "%s\n", (const char *)&head[1]);
4070 if ( result < 0 )
4071 return result;
4072 }
4073 return 0;
4074}
4075
4076static int do_write_netcnf(sceNetCnfEnv_t *e, const char *path, int is_attach_cnf)
4077{
4078 int memsize;
4079 const char *fullpath;
4080
4081 memsize = (int)((char *)e->mem_ptr - (char *)e->mem_base);
4082 if ( e->f_verbose )
4083 printf("netcnf: dir=%s path=%s\n", e->dir_name ? e->dir_name : "NULL", path ? path : "NULL");
4084 fullpath = do_handle_netcnf_prerw(e, path);
4085 if ( !fullpath )
4086 return -1;
4087 if ( e->f_verbose )
4088 {
4089 printf("netcnf: writing \"%s\" as ", fullpath);
4090 if ( is_attach_cnf )
4091 printf("ATTACH_CNF");
4092 else
4093 printf("NET_CNF");
4094 printf("\n");
4095 }
4096 if ( !is_attach_cnf || e->f_no_decode )
4097 {
4098 int fd;
4099 int writeres;
4100
4101 fd = do_open_netcnf(fullpath, 1538, 511);
4102 if ( fd < 0 )
4103 {
4104 e->file_err += 1;
4105 return (fd == -EIO) ? -18 : -3;
4106 }
4107 writeres = do_write_netcnf_no_encode(fd, e->mem_base, memsize);
4108 if ( memsize != writeres )
4109 {
4110 e->file_err += 1;
4111 do_close_netcnf(fd);
4112 return (writeres == -EIO) ? -18 : -5;
4113 }
4114 do_close_netcnf(fd);
4115 }
4116 else
4117 {
4118 if ( do_write_netcnf_encode(fullpath, e->mem_base, memsize) < 0 )
4119 {
4120 e->file_err += 1;
4121 return -1;
4122 }
4123 }
4124 return 0;
4125}
4126
4127static int do_export_netcnf_inner(sceNetCnfEnv_t *e, const char *arg_fname, struct sceNetCnfInterface *ifc)
4128{
4129 void *memalign;
4130 int result;
4131 struct sceNetCnfPair *pair_head;
4132
4133 memalign = (void *)(((uiptr)e->mem_base + 3) & (uiptr)~3);
4134 e->mem_base = memalign;
4135 e->mem_ptr = memalign;
4136 result = do_netcnf_sprintf_buffer(e, "%s\n\n", "# <Sony Computer Entertainment Inc.>");
4137 if ( result < 0 )
4138 return result;
4139 if ( ifc )
4140 {
4141 result = do_netcnf_other_write(e, g_options_attach_cnf, ifc);
4142 if ( result < 0 )
4143 return result;
4144 result = do_netcnf_phone_write(e, ifc);
4145 if ( result < 0 )
4146 return result;
4147 result = do_netcnf_net_write(e, ifc);
4148 if ( result < 0 )
4149 return result;
4150 result = do_netcnf_unknown_write(e, &ifc->unknown_list);
4151 if ( result < 0 )
4152 return result;
4153 return do_write_netcnf(e, arg_fname, 1);
4154 }
4155 for ( pair_head = e->root->pair_head; pair_head; pair_head = pair_head->forw )
4156 {
4157 result = do_netcnf_sprintf_buffer(
4158 e, "interface \"%S\" \"%S\" \"%S\"\n", pair_head->display_name, pair_head->attach_ifc, pair_head->attach_dev);
4159 if ( result < 0 )
4160 return result;
4161 }
4162 result = do_netcnf_other_write(e, g_options_net_cnf, e->root);
4163 if ( result < 0 )
4164 return result;
4165 result = do_netcnf_unknown_write(e, &e->root->unknown_list);
4166 if ( result < 0 )
4167 return result;
4168 return do_write_netcnf(e, arg_fname, 0);
4169}
4170
4171static int do_export_netcnf(sceNetCnfEnv_t *e)
4172{
4173 return ((e->req != 1 && e->req != 2) || do_export_netcnf_inner(e, e->arg_fname, (e->req == 1) ? 0 : e->ifc)) ? -1 : 0;
4174}
4175
4176static char *do_address_to_string_inner_element(char *dst, int srcbyte)
4177{
4178 char *tmpstk_ptr;
4179 char tmpstk[16];
4180
4181 tmpstk_ptr = tmpstk;
4182 if ( srcbyte < 0 )
4183 {
4184 *dst = '-';
4185 dst += 1;
4186 srcbyte = -srcbyte;
4187 }
4188 for ( ; srcbyte > 0; srcbyte /= 10 )
4189 {
4190 *tmpstk_ptr = srcbyte % 10 + '0';
4191 tmpstk_ptr += 1;
4192 }
4193 for ( ; tmpstk < tmpstk_ptr; tmpstk_ptr -= 1 )
4194 {
4195 *dst = tmpstk_ptr[-1];
4196 dst += 1;
4197 }
4198 return dst;
4199}
4200
4201static void do_address_to_string_inner(char *dst, unsigned int srcint)
4202{
4203 char *elm1;
4204
4205 elm1 = do_address_to_string_inner_element(dst, (srcint >> 24) & 0xFF);
4206 *elm1 = '.';
4207 elm1 = do_address_to_string_inner_element(elm1 + 1, (srcint >> 16) & 0xFF);
4208 *elm1 = '.';
4209 elm1 = do_address_to_string_inner_element(elm1 + 1, (srcint >> 8) & 0xFF);
4210 *elm1 = '.';
4211 elm1 = do_address_to_string_inner_element(elm1 + 1, srcint & 0xFF);
4212 *elm1 = 0;
4213}
4214
4215static int do_name_2_address_inner(unsigned int *dst, const char *buf)
4216{
4217 int prefixchkn;
4218 unsigned int i;
4219 int offsbase1;
4220 unsigned int tmpstk1[4];
4221
4222 i = 0;
4223 for ( prefixchkn = 0; prefixchkn < (int)(sizeof(tmpstk1) / sizeof(tmpstk1[0])); prefixchkn += 1 )
4224 {
4225 unsigned int base;
4226
4227 base = 10;
4228 if ( *buf == '0' )
4229 {
4230 base = 8;
4231 buf += 1;
4232 if ( *buf == 'x' || *buf == 'X' )
4233 {
4234 buf += 1;
4235 base = 16;
4236 }
4237 }
4238 for ( i = 0; isxdigit(*buf); i = i * base + (unsigned int)offsbase1 )
4239 {
4240 offsbase1 = *buf - '0';
4241 if ( !isdigit(*buf) )
4242 {
4243 offsbase1 = *buf - '7';
4244 if ( !isupper(*buf) )
4245 offsbase1 = *buf - 'W';
4246 }
4247 if ( offsbase1 >= (int)base )
4248 break;
4249 buf += 1;
4250 }
4251 if ( prefixchkn > 0 && (unsigned int)tmpstk1[prefixchkn - 1] >= 0x100 )
4252 return 0;
4253 tmpstk1[prefixchkn] = i;
4254 if ( *buf != '.' )
4255 break;
4256 buf += 1;
4257 }
4258 if ( *buf && *buf != ' ' )
4259 return 0;
4260 switch ( prefixchkn )
4261 {
4262 case 0:
4263 break;
4264 case 1:
4265 if ( (i >> 24) )
4266 return 0;
4267 i |= tmpstk1[0] << 24;
4268 break;
4269 case 2:
4270 if ( (i >> 16) )
4271 return 0;
4272 i |= (tmpstk1[0] << 24) | (tmpstk1[1] << 16);
4273 break;
4274 case 3:
4275 if ( (i >> 8) )
4276 return 0;
4277 i |= (tmpstk1[0] << 24) | (tmpstk1[1] << 16) | (tmpstk1[2] << 8);
4278 break;
4279 default:
4280 return 0;
4281 }
4282 *dst = i;
4283 return 1;
4284}
4285
4286static int do_conv_a2s_inner(char *sp_, char *dp_, int len)
4287{
4288 int len_minus_three;
4289 int curindx1;
4290 char *dp_ptroffs1;
4291 char *dp_ptroffs2;
4292 char *dp_ptroffs3;
4293
4294 len_minus_three = len - 3;
4295 curindx1 = 0;
4296 if ( len_minus_three <= 0 )
4297 return -19;
4298 *dp_ = '"';
4299 dp_ptroffs1 = dp_ + 1;
4300 *dp_ptroffs1 = '"';
4301 dp_ptroffs1 += 1;
4302 *dp_ptroffs1 = ' ';
4303 dp_ptroffs2 = dp_ptroffs1 + 1;
4304 while ( 1 )
4305 {
4306 for ( ; *sp_ == ' ' || *sp_ == '\t'; sp_ += 1 )
4307 ;
4308 if ( !*sp_ )
4309 break;
4310 if ( (*sp_ != 'A' && *sp_ != 'a') || (sp_[1] != 'T' && sp_[1] != 't') )
4311 return 0;
4312 for ( ; *sp_ && *sp_ != ' ' && *sp_ != '\t'; sp_ += 1 )
4313 {
4314 len_minus_three -= 1;
4315 if ( len_minus_three <= 0 )
4316 return -19;
4317 if ( *sp_ == '-' || *sp_ == '\\' || *sp_ == '"' || *sp_ == '^' )
4318 {
4319 len_minus_three -= 1;
4320 if ( len_minus_three <= 0 )
4321 return -19;
4322 *dp_ptroffs2 = '\\';
4323 dp_ptroffs2 += 1;
4324 }
4325 *dp_ptroffs2 = *sp_;
4326 dp_ptroffs2 += 1;
4327 }
4328 len_minus_three -= 4;
4329 if ( len_minus_three <= 0 )
4330 return -19;
4331 *dp_ptroffs2 = ' ';
4332 dp_ptroffs3 = dp_ptroffs2 + 1;
4333 *dp_ptroffs3 = 'O';
4334 dp_ptroffs3 += 1;
4335 *dp_ptroffs3 = 'K';
4336 dp_ptroffs3 += 1;
4337 *dp_ptroffs3 = ' ';
4338 dp_ptroffs2 = dp_ptroffs3 + 1;
4339 curindx1 += 1;
4340 }
4341 if ( curindx1 <= 0 )
4342 return 0;
4343 if ( (len_minus_three - 2) <= 0 )
4344 return -19;
4345 strcpy(dp_ptroffs2, "\\c");
4346 return 1;
4347}
4348
4349static int do_conv_s2a_inner(char *sp_, char *dp_, int len)
4350{
4351 int curindx1;
4352 char *sp_minus_one1;
4353 char *sp_ptroffs1;
4354 char *sp_ptroffs2;
4355 char *sp_ptroffs3;
4356 char *sp_ptroffs4;
4357
4358 curindx1 = 0;
4359 for ( ; *sp_ == ' ' || *sp_ == '\t'; sp_ += 1 )
4360 ;
4361 sp_minus_one1 = sp_;
4362 if ( *sp_minus_one1 != '"' || sp_minus_one1[1] != '"' || (sp_minus_one1[2] != ' ' && sp_minus_one1[2] != '\t') )
4363 return 0;
4364 sp_ptroffs1 = sp_minus_one1 + 3;
4365 while ( 1 )
4366 {
4367 for ( ; *sp_ptroffs1 == ' ' || *sp_ptroffs1 == '\t'; sp_ptroffs1 += 1 )
4368 ;
4369 sp_ptroffs2 = sp_ptroffs1;
4370 if ( !*sp_ptroffs2 || *sp_ptroffs2 == '\\' )
4371 {
4372 if ( *sp_ptroffs2 != '\\' || sp_ptroffs2[1] != 'c' )
4373 return 0;
4374 sp_ptroffs4 = sp_ptroffs2 + 2;
4375 for ( ; *sp_ptroffs4 == ' ' || *sp_ptroffs4 == '\t'; sp_ptroffs4 += 1 )
4376 ;
4377 if ( *sp_ptroffs4 )
4378 return -19;
4379 if ( curindx1 <= 0 )
4380 return 0;
4381 if ( (int)(len - 1) < 0 )
4382 return -19;
4383 *dp_ = 0;
4384 return 1;
4385 }
4386 if ( (*sp_ptroffs2 != 'A' && *sp_ptroffs2 != 'a') || (sp_ptroffs2[1] != 'T' && sp_ptroffs2[1] != 't') )
4387 return 0;
4388 if ( curindx1 > 0 )
4389 {
4390 len -= 1;
4391 if ( len <= 0 )
4392 return -19;
4393 *dp_ = ' ';
4394 dp_ += 1;
4395 }
4396 sp_ptroffs2 += 1;
4397 if ( (sp_ptroffs2[-1]) != ' ' )
4398 {
4399 sp_ptroffs2 -= 1;
4400 while ( *sp_ptroffs2 != '\t' )
4401 {
4402 len -= 1;
4403 if ( len <= 0 )
4404 return -19;
4405 if ( *sp_ptroffs2 == '\\' )
4406 {
4407 if ( sp_ptroffs2[1] != '-' && sp_ptroffs2[1] != '\\' && sp_ptroffs2[1] != '"' && sp_ptroffs2[1] != '^' )
4408 return 0;
4409 sp_ptroffs2 += 1;
4410 }
4411 *dp_ = *sp_ptroffs2;
4412 dp_ += 1;
4413 sp_ptroffs2 += 1;
4414 if ( !*sp_ptroffs2 || *sp_ptroffs2 == ' ' )
4415 break;
4416 }
4417 }
4418 for ( ; *sp_ptroffs2 == ' ' || *sp_ptroffs2 == '\t'; sp_ptroffs2 += 1 )
4419 ;
4420 sp_ptroffs3 = sp_ptroffs2;
4421 if ( *sp_ptroffs3 != 'O' || sp_ptroffs3[1] != 'K' || (sp_ptroffs3[2] != ' ' && sp_ptroffs3[2] != '\t') )
4422 return 0;
4423 sp_ptroffs1 = sp_ptroffs3 + 3;
4424 curindx1 += 1;
4425 }
4426}
4427
4428static int do_check_aolnet(const char *auth_name)
4429{
4430 int i;
4431 const char *periodpos;
4432
4433 if ( strncmp(auth_name, "aolnet/", 7) )
4434 return 0;
4435 periodpos = auth_name;
4436 for ( i = 0; periodpos; i += 1 )
4437 {
4438 periodpos = strchr(periodpos, '.');
4439 if ( periodpos )
4440 periodpos += 1;
4441 }
4442 return (i != 5) ? 0 : -20;
4443}
4444
4445static int do_check_authnet(char *argst, char *arged)
4446{
4447 char *i;
4448 char *j;
4449
4450 for ( i = arged; argst < i && i[-1] < '!'; i -= 1 )
4451 ;
4452 *i = 0;
4453 for ( j = argst; *j && isspace(*j); j += 1 )
4454 ;
4455 if ( !strncmp(j, "auth_name", 9) )
4456 {
4457 int result;
4458
4459 for ( ; *j && !isspace(*j); j += 1 )
4460 ;
4461 for ( ; *j && isspace(*j); j += 1 )
4462 ;
4463 if ( *j == '"' )
4464 j += 1;
4465 result = do_check_aolnet(j);
4466 if ( result < 0 )
4467 return result;
4468 }
4469 return 0;
4470}
4471
4472static int do_read_check_netcnf(const char *netcnf_path, int type, int no_check_magic, int no_decode)
4473{
4474 int read_res2;
4475 char *heapmem;
4476 int errretres;
4477 char *curheapptr1;
4478 char *heapmem_2;
4479
4480 switch ( type )
4481 {
4482 case 0:
4483 case 2:
4484 return 0;
4485 default:
4486 return -10;
4487 case 1:
4488 break;
4489 }
4490 read_res2 = no_decode ? do_read_netcnf_no_decode(netcnf_path, &g_read_check_netcnf_heapptr) :
4491 do_read_netcnf_decode(netcnf_path, &g_read_check_netcnf_heapptr);
4492 if ( read_res2 < 0 )
4493 return read_res2;
4494 heapmem = (char *)do_alloc_heapmem(1024);
4495 errretres = 0;
4496 if ( !heapmem )
4497 {
4498 do_free_heapmem(g_read_check_netcnf_heapptr);
4499 return -2;
4500 }
4501 curheapptr1 = g_read_check_netcnf_heapptr;
4502 heapmem_2 = heapmem;
4503 if (
4504 no_check_magic
4505 && (read_res2 < 36 || strncmp(g_read_check_netcnf_heapptr, "# <Sony Computer Entertainment Inc.>", 36)) )
4506 {
4507 int i;
4508
4509 printf("netcnf: decoding error (magic=\"");
4510 for ( i = 0; i < read_res2 && i < 36; i += 1 )
4511 {
4512 printf("%c", (unsigned int)((u8)curheapptr1[i] - 32) >= 0x5F ? '?' : (char)(u8)curheapptr1[i]);
4513 }
4514 errretres = -15;
4515 printf("\")\n");
4516 }
4517 if ( !errretres && read_res2 > 0 )
4518 {
4519 read_res2 -= 1;
4520 for ( ; read_res2 > 0; read_res2 -= 1 )
4521 {
4522 if ( *curheapptr1 == '\n' )
4523 {
4524 if ( heapmem < heapmem_2 && heapmem_2[-1] == '\\' )
4525 {
4526 heapmem_2 -= 1;
4527 }
4528 else
4529 {
4530 *heapmem_2 = 0;
4531 errretres = do_check_authnet(heapmem, heapmem_2);
4532 heapmem_2 = heapmem;
4533 if ( errretres < 0 )
4534 break;
4535 }
4536 }
4537 else
4538 {
4539 if ( heapmem_2 < &heapmem[1023] && *curheapptr1 != '\r' )
4540 {
4541 *heapmem_2 = *curheapptr1;
4542 heapmem_2 += 1;
4543 }
4544 }
4545 curheapptr1 += 1;
4546 }
4547 }
4548 if ( !errretres && heapmem < heapmem_2 )
4549 errretres = do_check_authnet(heapmem, heapmem_2);
4550 do_free_heapmem(g_read_check_netcnf_heapptr);
4551 do_free_heapmem(heapmem);
4552 return errretres;
4553}
4554
4555static int do_check_provider_inner(const sceNetCnfEnv_t *e, int type)
4556{
4557 switch ( type )
4558 {
4559 case 0:
4560 case 2:
4561 return 0;
4562 case 1:
4563 {
4564 if ( !e || !e->ifc )
4565 return -14;
4566 if ( e->ifc->auth_name )
4567 {
4568 int result;
4569
4570 result = do_check_aolnet((const char *)e->ifc->auth_name);
4571 if ( result < 0 )
4572 return result;
4573 }
4574 return 0;
4575 }
4576 default:
4577 return -10;
4578 }
4579}
4580
4581static const char *do_handle_netcnf_dirname(const char *fpath, const char *entry_buffer, char *netcnf_file_path)
4582{
4583 const char *entry_buffer_1;
4584 const char *fpath_1;
4585 const char *fpath_1_minus_1;
4586 const char *fpath_2;
4587 char *i;
4588 const char *entry_buffer_2;
4589
4590 if ( !entry_buffer || !*entry_buffer )
4591 return 0;
4592 for ( entry_buffer_1 = entry_buffer; *entry_buffer_1; entry_buffer_1 += 1 )
4593 {
4594 if ( *entry_buffer_1 == ':' )
4595 return entry_buffer;
4596 }
4597 if ( !fpath || !*fpath )
4598 return entry_buffer;
4599 for ( fpath_1 = fpath; fpath_1[1]; fpath_1 += 1 )
4600 ;
4601 fpath_1_minus_1 = fpath_1 - 1;
4602 if ( fpath < fpath_1_minus_1 || *entry_buffer == '/' || *entry_buffer == '\\' )
4603 {
4604 for ( ; fpath < fpath_1_minus_1 && *fpath_1_minus_1 != ':'; fpath_1_minus_1 -= 1 )
4605 ;
4606 if ( fpath <= fpath_1_minus_1 && (*fpath_1_minus_1 == ':' || *fpath_1_minus_1 == '/' || *fpath_1_minus_1 == '\\') )
4607 {
4608 fpath_1_minus_1 += 1;
4609 }
4610 }
4611 else if ( fpath <= fpath_1_minus_1 && *fpath_1_minus_1 != ':' )
4612 {
4613 for ( ; fpath < fpath_1_minus_1 && *fpath_1_minus_1 != ':' && *fpath_1_minus_1 != '/' && *fpath_1_minus_1 != '\\';
4614 fpath_1_minus_1 -= 1 )
4615 ;
4616 if ( *fpath_1_minus_1 == ':' || *fpath_1_minus_1 == '/' || *fpath_1_minus_1 == '\\' )
4617 {
4618 fpath_1_minus_1 += 1;
4619 }
4620 }
4621 fpath_2 = fpath;
4622 for ( i = netcnf_file_path; fpath_2 < fpath_1_minus_1; i += 1 )
4623 {
4624 *i = *fpath_2;
4625 fpath_2 += 1;
4626 }
4627 for ( entry_buffer_2 = entry_buffer; *entry_buffer_2; entry_buffer_2 += 1 )
4628 {
4629 *i = *entry_buffer_2;
4630 i += 1;
4631 }
4632 *i = 0;
4633 return netcnf_file_path;
4634}
4635
4636static int do_get_filesize_inner(int fd)
4637{
4638 int lseek_end_res;
4639 int lseek_start_res;
4640
4641 lseek_end_res = lseek(fd, 0, 2);
4642 if ( lseek_end_res < 0 )
4643 return (lseek_end_res != -EIO) ? -6 : -18;
4644 lseek_start_res = lseek(fd, 0, 0);
4645 return (lseek_start_res < 0) ? ((lseek_start_res != -EIO) ? -6 : -18) : lseek_end_res;
4646}
4647
4648static int is_special_file_path(const char *netcnf_path)
4649{
4650 switch ( g_callbacks.type )
4651 {
4652 case 1:
4653 return !strncmp(netcnf_path, "mc", 2) ? 1 : 0;
4654 case 2:
4655 return !strncmp(netcnf_path, "ext", 3) ? 1 : 0;
4656 default:
4657 return 1;
4658 }
4659}
4660
4661static void do_init_callback_handles(void)
4662{
4663 int i;
4664
4665 for ( i = 0; i < (int)(sizeof(g_callback_handle_infos) / sizeof(g_callback_handle_infos[0])); i += 1 )
4666 {
4667 g_callback_handle_infos[i].m_fd = -1;
4668 g_callback_handle_infos[i].m_filesize = 0;
4669 g_callback_handle_infos[i].m_allocstate = 0;
4670 }
4671}
4672
4673static int do_get_empty_callback_handle(int in_fd, int in_allocstate)
4674{
4675 int i;
4676
4677 for ( i = 0; i < (int)(sizeof(g_callback_handle_infos) / sizeof(g_callback_handle_infos[0])); i += 1 )
4678 {
4679 if ( g_callback_handle_infos[i].m_fd == -1 )
4680 {
4681 g_callback_handle_infos[i].m_fd = in_fd;
4682 g_callback_handle_infos[i].m_allocstate = in_allocstate;
4683 g_open_callback_handle_count += 1;
4684 return i;
4685 }
4686 }
4687 return -1;
4688}
4689
4690static int do_filesize_callback_handles(int in_fd, int in_allocstate)
4691{
4692 int i;
4693
4694 for ( i = 0; i < (int)(sizeof(g_callback_handle_infos) / sizeof(g_callback_handle_infos[0])); i += 1 )
4695 {
4696 if (
4697 g_callback_handle_infos[i].m_fd == in_fd
4698 && (g_callback_handle_infos[i].m_allocstate == in_allocstate || !in_allocstate) )
4699 {
4700 return i;
4701 }
4702 }
4703 return -1;
4704}
4705
4706static void do_clear_callback_handles(int fd, int allocmatch)
4707{
4708 int i;
4709
4710 for ( i = 0; i < (int)(sizeof(g_callback_handle_infos) / sizeof(g_callback_handle_infos[0])); i += 1 )
4711 {
4712 if ( g_callback_handle_infos[i].m_fd == fd && g_callback_handle_infos[i].m_allocstate == allocmatch )
4713 {
4714 g_callback_handle_infos[i].m_fd = -1;
4715 g_callback_handle_infos[i].m_allocstate = 0;
4716 g_open_callback_handle_count -= 1;
4717 break;
4718 }
4719 }
4720}
4721
4722static const char *do_colon_callback_handles(const char *netcnf_path, char *device)
4723{
4724 char *index_res;
4725 u32 devnameend;
4726
4727 index_res = index(netcnf_path, ':');
4728 if ( !index_res )
4729 return 0;
4730 devnameend = (u32)(int)(index_res - netcnf_path) + 1;
4731 if ( devnameend >= 17 )
4732 return 0;
4733 memcpy(device, netcnf_path, (u32)devnameend);
4734 device[devnameend] = 0;
4735 return (strlen(index_res + 1) + 1 < 257) ? (index_res + 1) : 0;
4736}
4737
4738static int do_open_netcnf(const char *netcnf_path, int file_flags, int file_mode)
4739{
4740 const char *cbind;
4741 int openret1;
4742 int empty_callback_handle;
4743 char pathconcat[16];
4744 int filesz1;
4745
4746 if ( !g_callbacks.open || !is_special_file_path(netcnf_path) )
4747 return open(netcnf_path, file_flags, file_mode);
4748 if ( g_open_callback_handle_count >= (int)(sizeof(g_callback_handle_infos) / sizeof(g_callback_handle_infos[0])) )
4749 return -EPERM;
4750 cbind = do_colon_callback_handles(netcnf_path, pathconcat);
4751 if ( !cbind )
4752 return -EPERM;
4753 openret1 = g_callbacks.open(pathconcat, cbind, file_flags, file_mode, &filesz1);
4754 if ( openret1 < 0 )
4755 return openret1;
4756 empty_callback_handle = do_get_empty_callback_handle(openret1, 1);
4757 strcpy(g_callback_handle_infos[empty_callback_handle].m_device, pathconcat);
4758 strcpy(g_callback_handle_infos[empty_callback_handle].m_pathname, cbind);
4759 g_callback_handle_infos[empty_callback_handle].m_buf = 0;
4760 g_callback_handle_infos[empty_callback_handle].m_bufpos = 0;
4761 g_callback_handle_infos[empty_callback_handle].m_filesize = filesz1;
4762 return openret1;
4763}
4764
4765static int do_read_callback_handles(int handlefd, int fd, void *ptr, int size)
4766{
4767 struct netcnf_callback_handle_info *cbh;
4768
4769 cbh = &g_callback_handle_infos[handlefd];
4770 if ( !cbh->m_bufpos )
4771 {
4772 cbh->m_buf = do_alloc_heapmem(cbh->m_filesize);
4773 if ( !cbh->m_buf )
4774 return -EPERM;
4775 if ( g_callbacks.read(fd, cbh->m_device, cbh->m_pathname, cbh->m_buf, 0, cbh->m_filesize) != cbh->m_filesize )
4776 {
4777 do_free_heapmem(cbh->m_buf);
4778 cbh->m_buf = 0;
4779 return -EPERM;
4780 }
4781 }
4782 memcpy(ptr, (char *)cbh->m_buf + cbh->m_bufpos, (u32)size);
4783 cbh->m_bufpos += size;
4784 return size;
4785}
4786
4787static int do_readfile_netcnf(int fd, void *ptr, int size)
4788{
4789 int cbind;
4790
4791 if ( !g_callbacks.read )
4792 return read(fd, ptr, size);
4793 cbind = do_filesize_callback_handles(fd, 1);
4794 return (cbind == -1) ? read(fd, ptr, size) : do_read_callback_handles(cbind, fd, ptr, size);
4795}
4796
4797static int do_write_netcnf_no_encode(int fd, void *ptr, int size)
4798{
4799 if ( !g_callbacks_set || g_callbacks.type == 2 )
4800 return write(fd, ptr, size);
4801 printf("[err] netcnf write()\n");
4802 return -EPERM;
4803}
4804
4805static int do_dopen_wrap(const char *fn)
4806{
4807 if ( !g_callbacks_set || g_callbacks.type == 2 )
4808 {
4809#ifdef _IOP
4810 return dopen(fn);
4811#else
4812 (void)fn;
4813 return -EPERM;
4814#endif
4815 }
4816 printf("[err] netcnf dopen()\n");
4817 return -EPERM;
4818}
4819
4820static int do_dread_wrap(int fn, iox_dirent_t *buf)
4821{
4822 if ( !g_callbacks_set || g_callbacks.type == 2 )
4823 {
4824#ifdef _IOP
4825 return dread(fn, buf);
4826#else
4827 (void)fn;
4828 (void)buf;
4829 return -EPERM;
4830#endif
4831 }
4832 printf("[err] netcnf dread()\n");
4833 return -EPERM;
4834}
4835
4836static int do_remove_wrap(const char *fn)
4837{
4838 if ( !g_callbacks_set || g_callbacks.type == 2 )
4839 return remove(fn);
4840 printf("[err] netcnf remove()\n");
4841 return -EPERM;
4842}
4843
4844static void do_close_netcnf(int fd)
4845{
4846 int cbind;
4847
4848 if ( !g_callbacks.close )
4849 {
4850 close(fd);
4851 return;
4852 }
4853 cbind = do_filesize_callback_handles(fd, 1);
4854 if ( cbind == -1 )
4855 {
4856 close(fd);
4857 return;
4858 }
4859 g_callbacks.close(fd);
4860 do_free_heapmem(g_callback_handle_infos[cbind].m_buf);
4861 g_callback_handle_infos[cbind].m_buf = 0;
4862 do_clear_callback_handles(fd, 1);
4863}
4864
4865static void do_dclose_wrap(int fd)
4866{
4867 if ( !g_callbacks_set || g_callbacks.type == 2 )
4868 {
4869#ifdef _IOP
4870 dclose(fd);
4871#else
4872 (void)fd;
4873#endif
4874 return;
4875 }
4876 printf("[err] netcnf dclose()\n");
4877}
4878
4879static int do_filesize_netcnf(int fd)
4880{
4881 int cbind;
4882
4883 cbind = do_filesize_callback_handles(fd, 0);
4884 return (cbind == -1) ? do_get_filesize_inner(fd) : g_callback_handle_infos[cbind].m_filesize;
4885}
4886
4887static void do_getstat_wrap(const char *fn, iox_stat_t *stx)
4888{
4889 if ( !g_callbacks_set || g_callbacks.type == 2 )
4890 {
4891#ifdef _IOP
4892 getstat(fn, stx);
4893#else
4894 {
4895 struct stat st;
4896
4897 stat(fn, &st);
4898 stx->size = (unsigned int)(int)st.st_size;
4899 }
4900#endif
4901 return;
4902 }
4903 printf("[err] netcnf getstat()\n");
4904}
4905
4906static void do_chstat_mode_copyprotect_wrap(const char *fn)
4907{
4908#ifdef _IOP
4909 iox_stat_t statmode;
4910#endif
4911
4912 if ( !g_callbacks_set || g_callbacks.type == 2 )
4913 {
4914#ifdef _IOP
4915 do_getstat_wrap(fn, &statmode);
4916 statmode.mode |= 8u;
4917 chstat(fn, &statmode, 1u);
4918#else
4919 (void)fn;
4920#endif
4921 return;
4922 }
4923 printf("[err] netcnf chstat()\n");
4924}
4925
4926static void do_set_callback_inner(sceNetCnfCallback_t *pcallback)
4927{
4928 if ( pcallback )
4929 {
4930 g_callbacks.type = pcallback->type;
4931 g_callbacks.open = pcallback->open;
4932 g_callbacks.read = pcallback->read;
4933 g_callbacks.close = pcallback->close;
4934 g_callbacks_set = 1;
4935 }
4936 else
4937 {
4938 memset(&g_callbacks, 0, sizeof(g_callbacks));
4939 g_callbacks_set = 0;
4940 }
4941 do_init_callback_handles();
4942}
4943
4944#ifdef _IOP
4945static int do_init_heap(void)
4946{
4947 if ( g_netcnf_heap )
4948 return -2;
4949 g_netcnf_heap = CreateHeap(1024, 1);
4950 return g_netcnf_heap ? 0 : -1;
4951}
4952#endif
4953
4954static void *do_alloc_heapmem(int nbytes)
4955{
4956#ifdef _IOP
4957 return AllocHeapMemory(g_netcnf_heap, nbytes);
4958#else
4959 return malloc((size_t)nbytes);
4960#endif
4961}
4962
4963static void do_free_heapmem(void *ptr)
4964{
4965#ifdef _IOP
4966 if ( ptr )
4967 FreeHeapMemory(g_netcnf_heap, ptr);
4968#else
4969 if ( ptr )
4970 free(ptr);
4971#endif
4972}
4973
4974#ifdef _IOP
4975static void do_delete_heap(void)
4976{
4977 DeleteHeap(g_netcnf_heap);
4978 g_netcnf_heap = 0;
4979}
4980#endif
#define EIO
Definition errno.h:29
#define EPERM
Definition errno.h:21
int sceCdRI(u8 *buffer, u32 *result)
Definition cdvdman.c:5673
u16 newflags
Definition loadcore.h:36