source: abuse/tags/pd/macabuse/src/net/mac/atalk.c @ 49

Last change on this file since 49 was 49, checked in by Sam Hocevar, 11 years ago
  • Imported original public domain release, for future reference.
  • Property svn:keywords set to Id
File size: 18.6 KB
Line 
1#include "atalk.hpp"
2#include <stdlib.h>
3#include <string.h>
4
5#ifdef __POWERPC__
6DDPSocketListenerUPP DDPListener;
7UniversalProcPtr InitDDPListener;
8#else
9#include "ddplisten.hpp"
10#endif
11
12#define ATALK_DEBUG
13#define PACKET_TYPE 0xca
14
15//atalk_protocol atalk;
16
17short   mppRef;
18short   adspRef;
19
20/*
21FILE *log_file=NULL;
22extern int net_start();
23void net_log(char *st, void *buf, long size)
24{
25   
26  if (!log_file)
27  {
28    if (net_start())
29      log_file=fopen("client.log","wb");
30    else
31      log_file=fopen("server.log","wb");
32  }
33
34
35    fprintf(log_file,"%s%d - ",st,size);
36    int i;
37    for (i=0;i<size;i++)
38      if (isprint(*((unsigned char *)buf+i)))
39        fprintf(log_file,"%c",*((unsigned char *)buf+i));
40      else fprintf(log_file,"~");
41
42    fprintf(log_file," : ");
43
44    for (i=0;i<size;i++)
45    fprintf(log_file,"%02x, ",*((unsigned char *)buf+i),*((unsigned char *)buf+i));
46    fprintf(log_file,"\n");
47    fflush(log_file);
48
49} */
50
51//////////////////////////////////////////////////////////////////////
52//
53//  AppleTalk base socket Methods
54//
55
56atalk_base::atalk_base(int fd) : num(fd), select_flags(0)
57{
58}
59
60atalk_base::~atalk_base()
61{
62        atalk.free_socket(num);
63}
64
65//////////////////////////////////////////////////////////////////////
66//
67//  ADSP Socket Methods
68//
69
70adsp_socket::adsp_socket(int fd) : atalk_base(fd)
71{
72        dsp.ioCRefNum = adspRef;
73        dsp.csCode = dspInit;
74        dsp.u.initParams.ccbPtr = (TPCCB)&ccb;
75
76        // don't handle exceptions for now
77        dsp.u.initParams.userRoutine = 0;
78        // myDSPPBPtr->u.initParams.userRoutine = &myConnectionEvtUserRoutine;
79
80        dsp.u.initParams.sendQSize = QSIZE;                                     // size of send queue
81        dsp.u.initParams.sendQueue = &send_queue;               // send-queue buffer
82        dsp.u.initParams.recvQSize = QSIZE;                                     // size of receive queue
83        dsp.u.initParams.recvQueue = &recv_queue;               // receive-queue buffer
84        dsp.u.initParams.attnPtr = &attn_buff;                  // receive-attention buffer
85        dsp.u.initParams.localSocket = 0;                                               // let ADSP assign socket
86//      gDspCCB.myA5 = SetCurrentA5();                                                                                  // save A5 for the user routine
87
88        // establish a connection end
89
90        if (PBControl((ParmBlkPtr) &dsp, FALSE))
91                dprintf("ATALK ADSP Initialization Error\n");
92
93        conn = dsp.ccbRefNum;   // save CCB ref num for later
94}
95
96int adsp_socket::open(atalk_address *addr)
97{
98        OSErr err;
99       
100        dsp.ioCRefNum = adspRef;        // ADSP driver ref num
101        dsp.csCode = dspOpen;
102        dsp.ccbRefNum = conn;                   // connection ref num
103        dsp.u.openParams.remoteAddress = addr->addr;   
104        dsp.u.openParams.filterAddress.aNet = addr->addr.aNet;
105        dsp.u.openParams.filterAddress.aNode = addr->addr.aNode;
106        dsp.u.openParams.filterAddress.aSocket = 0;
107        dsp.u.openParams.ocMode = ocRequest;    // open connection mode
108        dsp.u.openParams.ocInterval = 6;                        // retry every second
109        dsp.u.openParams.ocMaximum = 255;                       // don't quit trying
110
111        // open a connection
112        if (err = PBControl((ParmBlkPtr)&dsp, FALSE))
113        {
114                dprintf("ATALK ADSP dspOpen error %d\n",err);
115                return err;
116        }
117        return 0;
118}
119
120void adsp_socket::cleanup()
121{
122        dsp.ioCRefNum = adspRef;                        // ADSP driver ref num
123        dsp.csCode = dspRemove;
124        dsp.ccbRefNum = conn;                                   // connection ref num
125        dsp.u.closeParams.abort = 0;    // don't close until everything is sent and received
126
127        if (PBControl((ParmBlkPtr) &dsp, FALSE))
128                dprintf("ATALK ADSP remove error");
129}
130
131int adsp_socket::ready_to_read()
132{
133        dsp.csCode = dspStatus;
134        PBControl((ParmBlkPtr)&dsp, 0);
135        return (dsp.u.statusParams.recvQPending != 0 || error());
136}
137
138int adsp_socket::error()
139{
140        return ( ccb.userFlags>=4 );
141}
142
143int adsp_socket::ready_to_write()
144{
145        dsp.ioCRefNum = adspRef;                        // ADSP driver ref num
146        dsp.csCode = dspStatus;
147        dsp.ioCompletion = 0;
148        dsp.ccbRefNum = conn;
149        PBControl((ParmBlkPtr)&dsp, 0);
150        return (dsp.u.statusParams.sendQPending == 0 || error());
151}
152
153int adsp_socket::read(void *buf, int size, net_address **addr)
154{
155  if (addr)
156        *addr=NULL;
157
158        do
159        {
160                if (error())
161                        return 0;
162                       
163                dsp.ioCRefNum = adspRef;                        // ADSP driver ref num
164                dsp.csCode = dspStatus;
165                dsp.ioCompletion = 0;
166                dsp.ccbRefNum = conn;
167                PBControl((ParmBlkPtr)&dsp, 0);
168        } while (dsp.u.statusParams.recvQPending < size);
169
170        int fu = dsp.u.statusParams.recvQPending;
171
172        dsp.ioCRefNum = adspRef;                        // ADSP driver ref num
173        dsp.csCode = dspRead;
174        dsp.ccbRefNum = conn;                                   // connection ref num
175        dsp.u.ioParams.reqCount = size;     // read this number of bytes
176        dsp.u.ioParams.dataPtr = (Ptr)buf;      // pointer to read buffer
177
178        // perform read
179        if (PBControl( (ParmBlkPtr)&dsp, FALSE))
180        {
181                dprintf("ATALK ADSP read error\n");
182                return 0;
183        }
184
185//      dprintf("ATALK DSP read %d of %d, wanted %d\n",
186//              dsp.u.ioParams.actCount,
187//              fu,
188//              size);
189
190  return dsp.u.ioParams.actCount;
191}
192
193int adsp_socket::write(void *buf, int size, net_address *addr)
194{
195  if (addr)
196        dprintf("Cannot change address for this socket type\n");
197
198        while (!ready_to_write())
199                if (error())
200                        return 0;
201
202        dsp.ioCRefNum = adspRef;               // ADSP driver ref num
203        dsp.csCode = dspWrite;
204        dsp.ccbRefNum = conn;                // connection ref num
205        dsp.u.ioParams.reqCount = size;  // write this numberof bytes
206        dsp.u.ioParams.dataPtr = buf;    // pointer to send queue
207        dsp.u.ioParams.eom = 0;          // 1 means last byte is logical end-of-message
208        dsp.u.ioParams.flush = 1;              // 1 means send data now
209
210        // perform write
211        if (PBControl( (ParmBlkPtr)&dsp, FALSE))
212        {
213                dprintf("ATALK ADSP Write error\n");
214                return 0;
215        }
216
217        int ret = dsp.u.ioParams.actCount;
218
219        while (!ready_to_write())
220                if (error())
221                        return 0;
222
223//      dprintf("ATALK DSP wrote %d of %d\n",ret,size);
224
225  return ret;
226}
227
228//////////////////////////////////////////////////////////////////////
229//
230//  ADSP Listener Socket Methods
231//
232
233adsp_listener::adsp_listener(int fd) : atalk_base(fd)
234{
235        // initialize listener with socket
236        dsp.ioCRefNum = adspRef;
237        dsp.csCode = dspCLInit;
238        dsp.u.initParams.ccbPtr = (TPCCB)&ccb;
239        dsp.u.initParams.localSocket = 0;  // get new "port"
240//      gDspCCB.myA5 = SetCurrentA5();                                                                                  // save A5 for the user routine
241
242        if (PBControl((ParmBlkPtr) &dsp, FALSE))
243                dprintf("ATALK Listener Initialization Error\n");
244
245        conn = dsp.ccbRefNum;   // save CCB ref num for later
246}
247
248int adsp_listener::listen(int port)
249{
250        // perform listen
251        dsp.ioCRefNum = adspRef;
252        dsp.csCode = dspCLListen;
253        dsp.ccbRefNum = conn;
254        dsp.ioResult = 1;
255       
256        // don't filter any addresses
257        dsp.u.openParams.filterAddress.aNet = 0;
258        dsp.u.openParams.filterAddress.aNode = 0;
259        dsp.u.openParams.filterAddress.aSocket = 0;
260//      gDspCCB.myA5 = SetCurrentA5();                                                                                  // save A5 for the user routine
261
262        if (PBControl((ParmBlkPtr) &dsp, TRUE))
263        {
264                dprintf("ATALK Listener Error\n");
265                return 0;
266        }
267        listening = 1;
268        return 1;
269}
270
271void adsp_listener::cleanup()
272{
273        dsp.csCode = dspCLRemove;
274        dsp.ioCompletion = 0;
275        dsp.ioCRefNum = adspRef;                        // ADSP driver ref num
276        dsp.ccbRefNum = conn;                                   // connection ref num
277        dsp.u.closeParams.abort = 1;    // close outstanding requests
278
279        if (PBControl((ParmBlkPtr) &dsp, FALSE))
280                dprintf("ATALK ADSP Listener remove error");
281}
282
283int adsp_listener::ready_to_read()
284{
285        return dsp.ioResult != 1;
286}
287
288net_socket *adsp_listener::accept(net_address *&addr)
289{
290        if (!ready_to_read())
291        {
292                dprintf("Listener not ready!\n");
293                return 0;
294        }
295        int fd = atalk.new_socket();
296       
297        adsp_socket *sock = new adsp_socket(fd);
298        atalk.socket[fd] = sock;
299       
300        addr = new atalk_address(&dsp.u.openParams.remoteAddress);
301       
302        sock->dsp.ioCRefNum = adspRef;
303        sock->dsp.csCode = dspOpen;
304        sock->dsp.ccbRefNum  = sock->conn;
305        sock->dsp.u.openParams.ocMode = ocAccept;
306        sock->dsp.u.openParams.ocInterval = 6;
307        sock->dsp.u.openParams.ocMaximum = 3;
308        sock->dsp.u.openParams.remoteCID = dsp.u.openParams.remoteCID;
309        sock->dsp.u.openParams.remoteAddress = dsp.u.openParams.remoteAddress;
310        sock->dsp.u.openParams.sendSeq = dsp.u.openParams.sendSeq;
311        sock->dsp.u.openParams.attnSendSeq = dsp.u.openParams.attnSendSeq;
312        sock->dsp.u.openParams.sendWindow = dsp.u.openParams.sendWindow;
313
314        if (PBControl((ParmBlkPtr) &sock->dsp, 0))
315                dprintf("ATALK Accept Error\n");
316
317        dsp.ioResult = 1;
318        listen(0);
319       
320        return sock;
321}
322
323//////////////////////////////////////////////////////////////////////
324//
325//  DDP Socket Methods
326//
327
328ddp_socket::ddp_socket(int fd) : atalk_base(fd)
329{
330        dprintf("DDP new\n");
331        ddp.abResult = 1;
332        ddp.ddpActCount = 0;
333        ddp.ddpReqCount = 586;
334        ddp.ddpDataPtr = buffer;
335
336        struct sDDPBuff *db = (struct sDDPBuff *)(&buffer[602]);
337
338        db->Start = (struct sPacket *)(&db->Data);
339        db->End = (struct sPacket *)((char*)db->Start + 602*16);
340        db->Tail = db->Head = db->Start;
341        db->Count = 0;
342
343        // note!!!! can only do once!
344        CallUniversalProc(InitDDPListener,
345                kRegisterBased
346                        | REGISTER_ROUTINE_PARAMETER(1, kRegisterA1, SIZE_CODE(sizeof(long))),
347                (char*)db);
348
349        atalk.mpp.MPPioRefNum = mppRef;
350        atalk.mpp.MPPioCompletion = 0L;
351        atalk.mpp.DDPsocket = 0;
352        atalk.mpp.DDPlistener = DDPListener;
353       
354        if (POpenSkt(&atalk.mpp,FALSE))
355                dprintf("ATALK DDP Open Socket Error\n");
356               
357        socket = atalk.mpp.DDPsocket;
358       
359        dprintf("allocated DDP at socket %d\n",socket);
360       
361        def_addr.aNet = 0;
362        def_addr.aNode = 0;
363        def_addr.aSocket = 0;
364}
365
366void ddp_socket::cleanup()
367{
368        atalk.mpp.MPPioRefNum = mppRef;
369        atalk.mpp.DDPsocket = socket;
370       
371        if (PCloseSkt(&atalk.mpp,FALSE))
372                dprintf("Error closing socket");
373}
374
375int ddp_socket::ready_to_read()
376{
377        return ( ((struct sDDPBuff *)(&buffer[602]))->Count > 0);
378}
379
380int ddp_socket::error()
381{
382        return 0;
383}
384
385//extern void do_flip(int num);
386
387int ddp_socket::read(void *buf, int size, net_address **addr)
388{
389        int cnt = size;
390       
391        while (!ready_to_read()) ;
392       
393//      do_flip(0);
394       
395        struct sDDPBuff *db = (struct sDDPBuff *)(&buffer[602]);
396        struct sPacket *pk = db->Tail;
397
398        cnt = (pk->Count<cnt)? pk->Count : cnt;
399        db->Count--;
400        memcpy(buf,&pk->Data,cnt);
401
402//              dprintf("DDP Got %d of %d from %d:%d:%d\n",cnt,size,
403//                      ddp.ddpAddress.aNet,ddp.ddpAddress.aNode,ddp.ddpAddress.aSocket);
404               
405        if (addr)
406                *addr = new atalk_address(&pk->Addr);
407
408        pk = (struct sPacket *)((char *)pk + 602);
409        if (pk>=db->End)
410                pk = db->Start;
411        db->Tail = pk;
412
413        return cnt;
414}
415
416int ddp_socket::write(void *buf, int size, net_address *address)
417{
418        char wds[14];
419        char header[20];
420        AddrBlock *addr;
421
422        if (address)
423                addr = &((atalk_address*)address)->addr;
424        else
425                addr = &def_addr;
426               
427        BuildDDPwds((Ptr)wds, (Ptr)header, (Ptr)buf, *addr, PACKET_TYPE, size);
428
429        atalk.mpp.DDP.ioCompletion = nil;
430        atalk.mpp.DDP.socket = socket;
431        atalk.mpp.DDP.checksumFlag = 0;
432        atalk.mpp.DDP.u.wdsPointer = (Ptr) &wds;
433
434        if (PWriteDDP(&atalk.mpp, FALSE))
435                dprintf("ATALK ADD Write error\n");
436
437//      dprintf("DDP Wrote %d to %d:%d:%d\n",size,
438//              addr->aNet, addr->aNode, addr->aSocket);
439
440        return 0;
441}
442
443//////////////////////////////////////////////////////////////////////
444//
445//  ATALK Protocol Methods
446//
447
448net_address *atalk_protocol::get_local_address()
449{
450        short node,net;
451       
452        GetNodeAddress(&node,&net);
453  atalk_address *a=new atalk_address(net,node);
454
455        return a;
456}
457
458net_address *atalk_protocol::get_node_address(char *&server_name, int def_port, int force_port)
459{
460        // not really used now
461
462        return 0;
463}
464
465net_socket *atalk_protocol::connect_to_server(net_address *addr, net_socket::socket_type sock_type)
466{
467  if (addr->protocol_type()!=net_address::ATALK)
468  {
469    fprintf(stderr,"Procotol type not supported in the executable\n");
470    return NULL;
471  }
472
473#ifdef ATALK_DEBUG
474        char s[256];
475        atalk_address *tmp = (atalk_address *)get_local_address();
476        tmp->store_string(s,256);
477        dprintf("[%s] trying to connect\n",s);
478
479        delete tmp;
480#endif
481
482        int fd = new_socket();
483
484  if (sock_type==net_socket::SOCKET_SECURE)
485  {
486        adsp_socket *s;
487    socket[fd] = s = new adsp_socket(fd);
488    s->open((atalk_address *)addr);
489    return socket[fd];
490  }
491  else
492  {
493        ddp_socket *d;
494    socket[fd] = d = new ddp_socket(fd);
495    d->def_addr = ((atalk_address*)addr)->addr;
496    return socket[fd];
497  }
498}
499
500net_socket *atalk_protocol::create_listen_socket(int &port, net_socket::socket_type sock_type)
501{
502        int fd = new_socket();
503
504        if (fd<0)
505                return 0;
506               
507        if (sock_type == net_socket::SOCKET_SECURE)
508        {
509                adsp_listener *l;
510
511                socket[fd] = l = new adsp_listener(fd);
512
513                listener = l->dsp.u.initParams.localSocket;
514                port = listener;
515       
516          if (l->listen(port)==0)
517        {   
518        delete l;
519        return 0;
520        }
521        }
522        else
523        {
524                ddp_socket *d;
525               
526                socket[fd] = d = new ddp_socket(fd);
527                port = d->get_socket();
528
529                // get rid of this when real.  used only by test program
530//              listener = port;
531        }
532
533        return socket[fd];
534}
535
536atalk_protocol::atalk_protocol()
537: ok(0), net_protocol(), registered(0), listener(0), querying(0)
538{
539        if (OpenDriver("\p.MPP", &mppRef))
540                return;
541
542        if (OpenDriver("\p.DSP", &adspRef))
543                return;
544
545        for (int i=0; i<MAXSOCKS; i++)
546                socket[i] = 0;
547        for (int i=0; i<MAXSOCKS-1; i++)
548                usage[i] = i+1;
549        usage[MAXSOCKS-1] = -1;
550        free = 0;
551
552        Handle listener;
553
554        listener = GetResource('SOCK',0);
555
556        if (!listener)
557                return;
558
559        HLock(listener);
560        InitDDPListener = (UniversalProcPtr)NewRoutineDescriptor((ProcPtr)(*listener+0x12),
561                kRegisterBased
562                 | REGISTER_ROUTINE_PARAMETER(1, kRegisterA1, SIZE_CODE(sizeof(long))),kM68kISA);
563        DDPListener = (UniversalProcPtr) (*listener+0x14);
564
565        // zone info initialization
566        last_block = 0;
567        last_pos = 1024;
568        num_zones = 0;
569        MyZone[0] = 1;
570        MyZone[1] = '*';
571
572        ok = 1;
573}
574
575int atalk_protocol::new_socket()
576{
577        int ret = free;
578       
579        if (ret >=0)
580        {
581                free = usage[free];
582                usage[ret] = -2;
583        }
584        else
585        {
586                dprintf("Out of atalk_protocol sockets");
587                exit(0);
588        }
589
590        dprintf("ATALK created fd = %d\n",ret);
591
592        return ret;
593}
594
595void atalk_protocol::free_socket(int num)
596{
597        if (usage[num] != -2)
598        {
599                dprintf("Freed bad atalk_socket %d\n",num);
600//              exit(0);
601        }
602        usage[num] = free;
603        free = num;
604        socket[num] = 0;
605
606        dprintf("ATALK freed fd = %d\n",num);
607}
608
609void atalk_protocol::cleanup()
610{
611        if (registered)
612                end_notify();
613        registered = 0;
614       
615        for (int i=0; i<MAXSOCKS; i++)
616                if (socket[i])
617                {
618                        delete socket[i];
619                        free_socket(i);
620                }
621}
622
623int atalk_protocol::select(int block)
624{
625        int i,count=0;
626
627        for (i=0; i<MAXSOCKS; i++)
628                if (socket[i])
629                        count += socket[i]->select_count();
630
631        return count;
632}
633
634net_socket *atalk_protocol::start_notify(int port, void *data, int len)
635{
636        if (registered)
637                return 0;
638               
639        // set up NBP names table entry
640        Name[0] = len;
641        memcpy(&Name[1],data,len);
642        NBPSetNTE((Ptr) &NTEName, Name, "\pAbuseServer", "\p*", listener);
643
644        // set up PRegisterName parameters
645        mpp.MPPioCompletion = 0L;
646        mpp.MPPioRefNum = mppRef;
647        mpp.NBP.interval = 7;                                                                                           // retransmit every 7*8=56 ticks
648        mpp.NBP.count = 3;                                                                                                      // and retry 3 times
649        mpp.NBP.nbpPtrs.entityPtr = (Ptr) &NTEName;     // name to register
650        mpp.NBP.parm.verifyFlag = 1;                                                            // verify this name
651
652#ifdef ATALK_DEBUG
653        char s[256];
654        atalk_address *tmp = (atalk_address *)get_local_address();
655        tmp->set_port(listener);
656        tmp->store_string(s,256);
657        dprintf("registering [%s] as %s\n",s,(char*)data);
658       
659        delete tmp;
660#endif
661
662        if (PRegisterName(&mpp, FALSE))
663                dprintf("ATALK Couldn't Register name\n");
664
665        registered = 1;
666
667        return 0;
668}
669
670void atalk_protocol::end_notify()
671{
672        EntityName      entity;
673
674        NBPSetEntity((Ptr) &entity, Name, "\pAbuseServer", "\p*");
675        mpp.MPPioCompletion = 0L;
676        mpp.MPPioRefNum = mppRef;
677        mpp.NBP.nbpPtrs.entityPtr = (Ptr)&entity;
678        if (PRemoveName(&mpp,FALSE))
679                dprintf("ATALK Unregister name error\n");
680}
681
682net_address *atalk_protocol::find_address(int port, char *name)
683// name should be a 256 byte buffer
684{
685        EntityName      entity;
686        atalk_address addr;
687
688        if (!querying)
689        {
690                NBPSetEntity((Ptr) &entity, "\p=", "\pAbuseServer", MyZone);
691               
692                nbp.MPPioRefNum = mppRef;
693                nbp.MPPioCompletion = 0L;
694                nbp.NBPinterval = 7;// retransmit every 7*8=56 ticks
695                nbp.NBPcount = 3;       // and retry 3 times
696                nbp.NBPentityPtr = (Ptr) &entity;
697                nbp.NBPretBuffPtr = (Ptr) Buff;
698                nbp.NBPretBuffSize = sizeof(Buff);
699                nbp.NBPmaxToGet = 10;
700                nbp.MPPioResult = 1;
701                nbp.NBPnumGotten = 0;
702       
703                if (PLookupName(&nbp,TRUE))
704                        dprintf("ATALK Name Lookup error\n");
705
706                querying = 1;
707               
708                return 0;
709        }
710        else
711        {
712                if (nbp.MPPioResult == 1)
713                        return 0;
714
715                querying = 0;
716               
717                if (nbp.MPPioResult != 0)
718                        return 0;
719               
720                for (int i=0; i<nbp.NBPnumGotten; i++)
721                {
722                        int found = 0;
723                       
724                        NBPExtract((Ptr)Buff,nbp.NBPnumGotten,i+1,&entity,&addr.addr);
725       
726            for (p_request p = servers.begin(); !found && p!=servers.end(); ++p)
727                if ( *((*p)->addr) == addr )
728                        found = 1;
729            for (p_request q = returned.begin(); !found && q!=returned.end(); ++q)
730                if ( *((*q)->addr) == addr )
731                        found = 1;
732                       
733                        if (!found)
734                        {
735                                RequestItem *r = new RequestItem;
736       
737                                for (int i=0; i<entity.objStr[0]; i++)
738                                        r->name[i] = entity.objStr[1+i];
739                                r->name[entity.objStr[0]] = 0;
740       
741                                r->addr = new atalk_address(&addr.addr);
742              servers.insert(r);
743#ifdef ATALK_DEBUG
744                                char s[256];
745                               
746                                addr.store_string(s,256);
747                                dprintf("accepted %s\n",s);
748#endif
749                        }
750                }
751       
752                if (servers.empty())
753                        return 0;
754       
755          servers.move_next(servers.begin_prev(), returned.begin_prev());
756                atalk_address *ret = (atalk_address*)(*returned.begin())->addr->copy();
757                strcpy(name,(*returned.begin())->name);
758       
759#ifdef ATALK_DEBUG
760                char s[256];
761               
762                ret->store_string(s,256);
763                dprintf("Found [%s]\n",s);
764#endif
765
766          return ret;
767        }
768}
769
770void atalk_protocol::reset_find_list()
771{
772        p_request p;
773       
774        for (p=servers.begin(); p!=servers.end(); ++p)
775                delete (*p)->addr;
776        for (p=returned.begin(); p!=returned.end(); ++p)
777                delete (*p)->addr;
778               
779  servers.erase_all();
780  returned.erase_all();
781}
782
783char ** atalk_protocol::GetZones(int &num)
784{
785        if (num_zones==0)
786        {
787                XPPParamBlock xppPB;
788                char buffer[578];
789                OSErr err = noErr;
790       
791                xppPB.XCALL.xppTimeout = 3;
792                xppPB.XCALL.xppRetry = 4;       
793                xppPB.XCALL.zipBuffPtr = buffer;       
794                xppPB.XCALL.zipLastFlag = 0;   
795                xppPB.XCALL.zipInfoField[1] = 0;       
796                xppPB.XCALL.zipInfoField[2] = 0;       
797               
798                while (xppPB.XCALL.zipLastFlag == 0 && err==noErr)
799                {
800                        err = GetZoneList(&xppPB, FALSE);
801                        if (err)
802                                dprintf("ATALK GetZoneList error %d\n",err);
803                        else
804                        {
805                                unsigned char *p = (unsigned char *)buffer;
806                                for (int i=0; i<xppPB.XCALL.zipNumZones; i++)
807                                {
808                                        AddZone(p);
809                                        p += (*p) + 1;
810                                }
811                        }
812                }
813        }
814       
815        num = num_zones;
816        return ZoneName;
817}
818
819void atalk_protocol::SetZone(char *name)
820{
821        int l = strlen(name);
822        MyZone[0] = l;
823        memcpy(&MyZone[1],name,l);
824}
825
826int atalk_protocol::GetMyZone(char *name)
827{
828        XPPParamBlock xppPB;
829        char buffer[33];
830        OSErr err = noErr;
831
832        xppPB.XCALL.xppTimeout = 3;
833        xppPB.XCALL.xppRetry = 4;       
834        xppPB.XCALL.zipBuffPtr = buffer;       
835        xppPB.XCALL.zipLastFlag = 0;   
836        xppPB.XCALL.zipInfoField[1] = 0;       
837        xppPB.XCALL.zipInfoField[2] = 0;       
838               
839        if (::GetMyZone(&xppPB, FALSE) == noErr)
840        {
841                memcpy(name,(char*)&buffer[1],buffer[0]);
842                name[buffer[0]] = 0;
843               
844                return 0;
845        }
846        else
847                return -1;
848}
849
850void atalk_protocol::AddZone(unsigned char *name)
851{
852        if (num_zones>=MAXZONENAMES)
853                return;
854
855        if (name[0] + last_pos + 1> 1024)
856        {
857                zones.insert(last_block = new sZoneBlock);
858                last_pos = 0;
859        }
860        char *ret = &last_block->Name[last_pos];
861        last_pos += name[0] + 1;
862       
863        memcpy(ret,(char*)&name[1],name[0]);
864        ret[name[0]] = 0;
865       
866        ZoneName[num_zones++] = ret;
867}
868
869void atalk_protocol::FreeZones()
870{
871        for (p_zoneblock p = zones.begin(); p != zones.end(); ++p)
872                delete (*p);
873               
874        zones.erase_all();
875        num_zones = 0;
876}
Note: See TracBrowser for help on using the repository browser.