TweetFollow Us on Twitter

MacSockets
Volume Number:7
Issue Number:12
Column Tag:Com Workshop

Related Info: Device Manager

Library for UNIX-based Clients

By Frank Storbeck, The Netherlands

Introduction.

From the moment that Apple Computer, Inc. came with its UDP-TCP/IP driver for the Macintosh, there was suddenly an increased potential for use of client-server programs as developed in the UNIX-world. Alas, Apple came with its own calls for addressing their UDP-TCP/IP driver (“.IPP”). The calls are essentially the standard low level PBOpen, PBControl and PBClose calls from the DeviceManager. The software includes a file named “TCPPB.h”, in which one finds the definitions for the various DeviceManager calls for the .IPP-driver. However it would be easy if one could use the standard UNIX calls for socket-based communication instead. This gives you the opportunity to port the UNIX software to the Mac. So I started to write a small library with the .IPP equivalents for the client-functions close, connect, recv, recvfrom, recvmsg, send, sendto, sendmsg, shutdown, and socket. To use the Mac as a server, you also need the equivalents of the functions accept, bind, listen and select, but, as I only needed the client-software, I left them out of the project. There are also some other constraints. These will be addressed in the next paragraph. To use the MacTCP software you need a Mac-512E or better and the appropriate LocalTalk- or Ethernet-compatible hardware.

The MacTCP package is available as a single-user developer kit (APDA™ # M0230LL/D). It contains the MacTCP software, a programmers guide and an administrator guide. A licence is required to redistribute the software.

Sockets.

In the manual titled “Network Programming Guide” from SUN®-microsystems (part number 800-3850-10) you can find a good explanation of the in’s and out’s of “Socket-Based Interprocess Communication”. Here only a short summary will follow.

Normally some host sets up a particular service. A client that wants to communicate with this server has to know the address of the host and what is called the port-number of the service. For the standard UNIX-services these port-numbers are “well known” (here I quoted from the manual pages), but if you want to start to offer a new service there is a range of numbers from which you can choose. In the example given here for the use of the code I choose the value 31768 (in a UNIX-system these values for the port-numbers can be found in the file /etc/services).

A socket-pair is a “two way communication channel between two processes”. Each of these processes has a socket that can be used both for sending and receiving of data to and from the other process. The processes may reside on the same or different hosts, but they have to use the same address domains, the same communication method and the same protocol. As I had to use the software for a special project for communication on board of a research vessel, I allowed some more constraints to the software: only internet addressing mode (AF_INET), stream-sockets (SOCK_STREAM) and of course the TCP-IP protocol are supported.

Normally a server-program runs on a host for as long as possible (i.e. between start-up and shut-down). It then waits for the action of some client-program. The client tries to connect to the server, sends a message that it wants some service and then waits for the answer from the server. This can go on for as long as the service is needed. Then the connection is closed down and the server waits for the next client to be served. It is also possible that a server works for more than one client simultaneously. In this case it has a socket for each of the various clients to be served.

The client and server programs

This scheme shows up in the sample code for client.c and server.c that can be found in the listing. They are examples of how to use the calls to the functions for the socket-based communication. After the server has been activated, the client can be started, and it sends the following message to the server:

From: client

To: server

Mssg: Hello server!

Then the server replies with another message:

From: server

To: client

Mssg: Hello client!\n

The server has to be run on some SUN workstation (because of the call bcopy, replace it eventually with the ANSI-C call memcpy, but beware, the order of the parameters is different; also there is a function bzero to clear the memory locations over some range - if not present, deactivate it: the locations will be overwritten by the message anyhow!) The client has been compiled with THINK-C (4.0) compiler. The THINK-C project must also contain the ANSI, MacTraps and UNIX libraries.

The client-program can also be run on a SUN workstation. Just activate the SUN_C macro.

Of course you can change client and server as you like. You can maintain the connection until the client sends some bye-bye message, messages can be sent in chunks etc. etc. Do as you like.

Diagram 1: Sequence for communication between some server and one or more clients.

Some notes on the library

MacTCP provides the use of an asynchronous notification routine. This means that when some exception occurs, a user specified function can be activated. This is here implemented by the function SockNotify, which is hidden to the user. It calls the function DoAlert that draws an alert box on the screen displaying the appropriate massage for some time. The default showing time is 4 seconds, but can be changed with the function SetDialogShowTime. When the time is zero or negative, no DialogBox will be shown. The function DoAlert is also used by the function perror. In this case a stopIcon and an OK-button are added. The DialogBox shows the error message until the user clicks on the OK-button. As the function cannot be sure that a resource for the DialogBox and its DialogItemList is available, it is built up in memory. Note that to use it, you must initialize the DialogManager etc., otherwise your Mac behaves like the mother of all field-battles. All this can be switched off by deactivating the MAC_APPL macro. In this case the messages will be shown on stderr, using the console-library from THINK-C.

There are some extra routines added: close_MacSocket, exit_MacSocket, perror_MacSocket, and strerror_MacSocket,. They are used to prevent direct calls to their UNIX and ANSI-C equivalents close, exit, perror and strerror. In the file MacSocket.h there are macros that make sure that these calls will be diverted to their equivalents in the MacSocket library. e.g., if you call close, close_MacSocket first tries to close a socket-based connection. If the socket doesn’t exist, it calls the standard function close. This is a particular noteworthy example: you might have a file descriptor with number 5 and a socket with number 5. The only way to close the file with file-descriptor 5 while keeping the socket with number 5 in good shape is calling close directly:

/* 1 */

#undef close /* to dactivate a call to close_MacSocket */
close(5);
#define close close_MacSocket /* to reactivate it */

The program includes some files that are not provided here: “types.h”, “socket.h, “in.h”, “netdb.h” and “TCPPB.h”. The first four come from the SUNOS 4.1 operating system and are copyrighted by the Regents of the University of California I am not sure if I can redistribute them, so they are not included. But if you want to port software from a UNIX-platform to the Mac, you must have access to them anyhow. The file “TCPPB.h” is copyrighted by Apple Computer, Inc.

Last note: the program was written using SUNOS 4.0. Now we are using version 4.1. There they don’t speak about “address families” but about “address protocols”. Hence the macro AF_INET has been renamed to AP_INET, but AF_INET still works.

Listings server.c:
/***
 ***
 *** To send data between stream sockets (having communication 
 *** style SOCK_STREAM)
 *** Code based on an example taken from SUN® Network Program
 *** ming Guide,chapter 10, A Socket-Based Interprocess 
 *** Communications Tutorial,Revision A, of 27 March 1990, 
 *** Fig. 10-11, pp. 270-271.
 ***/
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/time.h>
#include<netinet/in.h>
#include<netdb.h>
#include<stdio.h>
#define TRUE(1)
#define DATA“\nFrom: server\nTo:   client\nMssg: Hello client!\n”
#define Port(31768)

main()
{
 int    sock, length;
 struct sockaddr_in server;
 int    msgsock;
 char buf[1024];
 fd_set ready;
 struct timeval  to;

 /* Create socket. */
 sock = socket(AF_INET, SOCK_STREAM, 0);
 if (sock < 0)
 {
 perror(“Server--> opening stream socket”);
 exit(1);
 }
 /* Name socket using wildcards. */
 server.sin_family = AF_INET;
 server.sin_addr.s_addr = INADDR_ANY;
 server.sin_port = Port;
 if (bind(sock, (struct sockadd *)&server, sizeof server) < 0)
 {
 perror(“Server--> getting socket name”);
 exit(1);
 }
 printf(“Server--> Socket port #%d\n”, ntohs(server.sin_port));

 /* Start accepting connections. */
 listen(sock, 5);
 do
 {
 FD_ZERO(&ready);
 FD_SET(sock, &ready);
 to.tv_sec = 5;
 if (select(sock + 1, &ready, (fd_set *)0, (fd_set *)0, &to) < 0)
 {
 perror(“Server--> select”);
 continue;
 }
 if (FD_ISSET(sock, &ready))
 {
 msgsock = accept(sock, (struct sockaddr *) 0, (int *) 0);
 if (msgsock == -1)
 {
 perror(“Server--> accept”);
 }
 else
 {
 bzero(buf, sizeof buf);
 if ((length = recv(msgsock, buf, 1024, 0)) < 0)
 {
 perror(“Server--> reading stream message”);
 }
 else
 {
 buf[length] = ‘\0’;
 printf(“Server-->%s\n”, buf);
 }
 if (send(msgsock, DATA, sizeof DATA, 0) < 0)
 {
 perror(“Server--> sending steam message”);
 }
 }
 close(msgsock);
 }
 else
 {
 /* Do something else. */
 }
 } while (TRUE);
 exit(0);
}
Listing:  socket.h
/***
 *** Copyright (c) 1990 Rijksinstituut voor Visserijonderzoek.
 *** All rights reserved.
 ***
 *** Redistribution and use in source and binary forms are 
 *** permitted provided that this notice is preserved and that 
 *** due credit is given to the Rijksinstituut voor Visserijonderzoek 
at IJmuiden.
 *** This software is provided “as is” without express or implied warranty.
 ***
 *** @(#)MacSocket.h 1.2 91/01/25
 ***/

#ifndef _MacSocket_H_
#define _MacSocket_H_

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unix.h>
#include<DeviceMgr.h>

#include“types.h”
#include“socket.h”
#include“in.h”
#include“netdb.h”
#include“TCPPB.h”

#ifdef  LAB_VIEW

/* to prevent the use of the malloc() call in a LabVIEW CIN */
#define SockElmnttheSockElmnt
#define SizeOf(x)x
#define malloc(x)&x

#else

#define SizeOf sizeof

#endif  LAB_VIEW

#ifndef NIL
#define NIL ((void*) 0L)
#endif  NIL
#ifndef InFrontOfAll
#define InFrontOfAll ((Ptr) -1L)
#endif  InFrontOfAll
#ifndef True
#define True(1)
#endif  True
#ifndef False
#define False    (0)
#endif  False
#define Abort    True
#define ReportIt False
#define Asynchronous True
#define SynchronousFalse
#define ConnectTimeout  (15)
#define SendTimeout(15)
#define RecvTimeout(15)
#define CloseTimeout (15)
#define SockBufSize(16384)
#define UserDataSize (128)

#define noTCPDriver(-1)
#define invalidArgument (2)
#define nonSOCK_STREAM  (13)
#define nonSocket(38)
#define nonAF_INET (43)
#define noBufSpace (55)
#define commandInProgress (1)

/* to force the application first to use the MacSocket versions */
#define perror   perror_MacSocket
#define exitexit_MacSocket
#define close    close_MacSocket
#define strerror strerror_MacSocket

/* Prototypes */
intaccept(int s, struct sockaddr *addr, int addrlen);
intbind(int s, struct sockaddr *name, int namelen);
intclose_MacSocket(int s);
intconnect(int s, struct sockaddr_in *name, int namelen);
void  exit_MacSocket(int status);
intlisten(int s, int backlog);
void  perror_MacSocket(char *s);
intrecv(int s, char *msg, int len, int flags);
intrecvfrom(int s, char *msg, int len, int flags, struct sockaddr_in 
*from,
 int *fromlen);
intrecvmsg(int s, struct msghdr *msg, int flags);
intsend(int s, char *msg, int len, int flags);
intsendto(int s, char *msg, int len, int flags, struct sockaddr_in *to,
 int tolen);
intsendmsg(int s, struct msghdr *msg, int flags);
intshutdown(int s, int how);
#ifdef  MAC_APPL
void  SetDialogShowTime(int sec);
#endif  MAC_APPL
intsocket(int domain, int type, int protocol);
char* strerror_MacSocket(int errnum);

#endif _MacSocket_H_
Listing:  client.c
/***
 ***
 *** To send data between stream sockets (having communication style
 *** SOCK_STREAM)
 *** Code based on an example taken from SUN® Network Programming Guide,
 *** chapter 10, A Socket-Based Interprocess Communications Tutorial,
 *** Revision A, of 27 March 1990, Fig. 10-9, pp. 266-267.
 ***
 ***/

#ifdef  SUN_C
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<netdb.h>
#include<stdio.h>
#else SUN_C
/*
#define MAC_APPL
*/
#include<console.h>
#include“MacSocket.h”
#define bcopy(s1, s2, n)  memcpy((s2), (s1), (n))
#endif  SUN_C

#define Port(31768)
#define DATA“\nFrom: client\nTo:   server\nMssg: Hello server!\n”

main()
{
 int    sock, mssgSize;
 struct sockaddr_in server;
 union
 {
 long   address;
 unsigned char domain[4];
 } host;
 char buf[1024];
 
#ifdef  MAC_APPL
 /* prevent showing informative MacTCP/IP messages */
 SetDialogShowTime(0);
#endif  MAC_APPL
 
 /* Create socket. */
 sock = socket(AF_INET, SOCK_STREAM, 0);
 if (sock < 0)
 {
 perror(“opening stream socket”);
 exit(1);
 }
 /* Connect socket using address 192.6.1.30 and port# */
 server.sin_family = AF_INET;
 host.domain[0] = 192;
 host.domain[1] = 6;
 host.domain[2] = 1;
 host.domain[3] = 30;
 bcopy((char*)&host.address, (char*)&server.sin_addr, 4);
 server.sin_port = Port;

 if (connect(sock, (struct sockaddr_in *)&server, sizeof server) < 0)
 {
 perror(“connecting stream socket”);
 exit(1);
 }
 if (send(sock, DATA, sizeof DATA, 0) < 0)
 {
 perror(“writing on stream socket”);
 exit(1);
 }
 if ((mssgSize = recv(sock, buf, sizeof buf, 0)) < 0)
 {
 perror(“reading on stream socket”);
 exit(1);
 }
 buf[mssgSize] = ‘\0’;
 printf(“Client--> %s\n”, buf);
 close(sock);
 exit(0);
}
Listing:  MacSocket.c
/***
 *** Copyright (c) 1990 Rijksinstituut voor Visserijonderzoek, IJmuiden.
 *** All rights reserved.
 ***
 *** Redistribution and use in source and binary forms are permitted
 *** provided that this notice is preserved and that due credit is given
 *** to the Rijksinstituut voor Visserijonderzoek at IJmuiden.
 *** This software is provided “as is” without express or implied warranty.
 ***
 *** @(#)MacSocket.c 1.7 91/04/04
 ***/

/*
#define MAC_APPL
*/
#include“MacSocket.h”

#define Connected(0x01)

typedef struct SockElmnt
{
 int    number;
 struct SockElmnt*next;
 TCPiopbthePB;
 char   sockBuf[SockBufSize];
} SockElmnt, *SockElmntPtr, **SockElmntHdl;

#ifdef  MAC_APPL

#define LineLength (350)
#define AMargin  (13)
#define BMargin  (23)
#define IconSize (32)
#define DlogTop  (66)
#define DlogLeft (50)
#define ButtonHeight (22)
#define ButtonLength (59)

typedef struct AlertDitl
{
 unsigned short  nItems;
 Handle textHandle;
 Rect   textRect;
 unsigned char text;
 unsigned char textSize;
 char   textString[8];
 Handle buttonHandle;
 Rect   buttonRect;
 unsigned char button;
 unsigned char buttonSize;
 char   buttonString[2];
 Handle iconHandle;
 Rect   iconRect;
 unsigned char icon;
 unsigned char iconSize;
 unsigned short  iconId;
 Handle outlineHandle;
 Rect   outlineRect;
 unsigned char outline;
 unsigned char outlineSize;
} AlertDitl, *AlertDitlPtr, **AlertDitlHdl;

#endif  MAC_APPL

#ifdef  close
#undef  close
#endif  close

#ifdef  exit
#undef  exit
#ifdef  MAC_APPL
#define exit(s)  ExitToShell()
#endif  MAC_APPL
#endif  exit

#ifdef  perror
#undef  perror
#endif  perror

#ifdef  strerror
#undef  strerror
#endif  strerror

/**
 **
 ** local prototypes
 **
 **/
static  voidDoAlert(int alertId, char* s1, char* s2, char* s3, char* 
s4);
static  SockElmntPtr CreateSocketStruct(void);
static  SockElmntPtr FindSocketStruct(int);
static  int OpenTCPDriver(void);
static  pascal voidOutlineProc(DialogPtr thePtr, int theItem);
static  voidPollTCPDriver(TCPiopb *thePB);
static  int RemoveSocketStruct(int);
static  pascal voidSockNotify(StreamPtr tcpStream,
 unsigned short eventCode,
 Ptr userDataPtr,
 unsigned short terminReason,
 struct ICMPReport *icmpMsg);

/**
 **
 ** local variables
 **
 **/
static  int errno_MacSocket = noErr;
static  int ioRefNumTCP;
static  charmacSocketErrorMssg[128] = “no error!”;
static  int showTime = 4;
static  int sockNumber = 4;
static  SockElmntPtr theHeadPtr = NIL;
static  charTCPDriverName[] = “\p.IPP”;
static  chartheUserData[UserDataSize];
static  charTCPDriverNotOpened = True;

#ifdef  LAB_VIEW

static  SockElmnttheSockElmnt;

#endif  LAB_VIEW

/***
 ***
 *** Mac versions the standard Socket-based internet communication protocol:
 ***
 ***/

/**
 **
 ** Local functions
 **
 **/

/*
 *
 * CreateSocketStruct - creates a data structure for a particular socket 
into a
 * linked list
 *
 */
static  SockElmntPtr CreateSocketStruct()
{
 register SockElmntPtr  theSockPtr;
 
 if ((theSockPtr = (SockElmntPtr)malloc(SizeOf(SockElmnt))) == NIL)
 {
 errno_MacSocket = noBufSpace;
 return (NIL);
 }
 theSockPtr->next = theHeadPtr;
 theHeadPtr = theSockPtr;
 theSockPtr->number = ++sockNumber;
 return (theSockPtr);
}

#ifdef  MAC_APPL
/*
 *
 * DoAlert - shows an alert message on the screen. When alertId is negative,
 * no icon and OK-button are displayed. The Alert message is then “showTime”
 * seconds visible.
 *
 */
static void DoAlert(int alertId, char* s1, char* s2, char* s3, char* 
s4)
{
 AlertDitlPtr  theAlertDitlPtr;
 AlertDitlHdl  theAlertDitlHdl;
 DialogRecord  dlogRecord;
 DialogPtrtheDlogPtr;
 Rect   theBounds;
 int    theItem;
 int    textHeight;
 int    nChars;
 FontInfo theFont;
 
 if ((alertId < 0) && (showTime <= 0))
 {
 return;
 }
 
 theAlertDitlHdl = (AlertDitlHdl)NewHandle(sizeof(AlertDitl));
 if (theAlertDitlHdl != NIL)
 {
 HLock(theAlertDitlHdl);
 theAlertDitlPtr = * theAlertDitlHdl;
 
 nChars = (int)((unsigned char)*s1) +
 (int)((unsigned char)*s2) +
 (int)((unsigned char)*s3) +
 (int)((unsigned char)*s4);
 
 GetFontInfo(&theFont);
 textHeight = ((nChars * theFont.widMax) / LineLength + 1) *
 (theFont.ascent + theFont.descent + theFont.leading);
 if ((textHeight < IconSize) && (alertId >= 0))
 {
 textHeight = IconSize;
 }
 
 theAlertDitlPtr->nItems = (alertId >= 0) ? 3 : 0;
 
 theAlertDitlPtr->textHandle = ((void*) 0L);
 theAlertDitlPtr->textRect.top = AMargin - 3;
 theAlertDitlPtr->textRect.left = BMargin - 3;
 if (alertId >= 0)
 {
 theAlertDitlPtr->textRect.left += IconSize + BMargin;
 }
 theAlertDitlPtr->textRect.bottom =
 theAlertDitlPtr->textRect.top + textHeight;
 theAlertDitlPtr->textRect.right =
 theAlertDitlPtr->textRect.left + LineLength;
 theAlertDitlPtr->text = statText + itemDisable;
 theAlertDitlPtr->textSize = 8;
 theAlertDitlPtr->textString[0] = ‘^’;
 theAlertDitlPtr->textString[1] = ‘0’;
 theAlertDitlPtr->textString[2] = ‘^’;
 theAlertDitlPtr->textString[3] = ‘1’;
 theAlertDitlPtr->textString[4] = ‘^’;
 theAlertDitlPtr->textString[5] = ‘2’;
 theAlertDitlPtr->textString[6] = ‘^’;
 theAlertDitlPtr->textString[7] = ‘3’;
 
 if (alertId >= 0)
 {
 theAlertDitlPtr->buttonHandle = ((void*) 0L);
 theAlertDitlPtr->buttonRect.top =
 theAlertDitlPtr->textRect.bottom + AMargin;
 theAlertDitlPtr->buttonRect.right =
 theAlertDitlPtr->textRect.right;
 theAlertDitlPtr->buttonRect.bottom =
 theAlertDitlPtr->buttonRect.top + ButtonHeight;
 theAlertDitlPtr->buttonRect.left =
 theAlertDitlPtr->buttonRect.right - ButtonLength;
 theAlertDitlPtr->button = ctrlItem + btnCtrl;
 theAlertDitlPtr->buttonSize = 2;
 theAlertDitlPtr->buttonString[0] = ‘O’;
 theAlertDitlPtr->buttonString[1] = ‘K’;
 
 theAlertDitlPtr->iconHandle = ((void*) 0L);
 theAlertDitlPtr->iconRect.top = theAlertDitlPtr->textRect.top;
 theAlertDitlPtr->iconRect.left = BMargin - 3;
 theAlertDitlPtr->iconRect.bottom =
 theAlertDitlPtr->iconRect.top + IconSize;
 theAlertDitlPtr->iconRect.right =
 theAlertDitlPtr->iconRect.left + IconSize;
 theAlertDitlPtr->icon = iconItem + itemDisable;
 theAlertDitlPtr->iconSize = 2;
 theAlertDitlPtr->iconId = alertId;
 
 theAlertDitlPtr->outlineHandle = (Handle)&OutlineProc;
 theAlertDitlPtr->outlineRect.top = theAlertDitlPtr->buttonRect.top;
 theAlertDitlPtr->outlineRect.left = theAlertDitlPtr->buttonRect.left;
 theAlertDitlPtr->outlineRect.bottom =
 theAlertDitlPtr->buttonRect.bottom;
 theAlertDitlPtr->outlineRect.right = theAlertDitlPtr->buttonRect.right;
 theAlertDitlPtr->outline = userItem + itemDisable;
 theAlertDitlPtr->outlineSize = 0;
 }
 
 theBounds.top = DlogTop;
 theBounds.left = DlogLeft;
 theBounds.bottom = DlogTop + AMargin - 3;
 theBounds.bottom += (alertId >= 0) ?
 theAlertDitlPtr->buttonRect.bottom :
 theAlertDitlPtr->textRect.bottom;
 theBounds.right = DlogLeft + theAlertDitlPtr->textRect.right + AMargin 
- 3;
 
 HUnlock(theAlertDitlHdl);
 
 ParamText(s1, s2, s3, s4);
 theDlogPtr = NewDialog(&dlogRecord, &theBounds, “\p”, True, dBoxProc,
 InFrontOfAll, False, 0L, theAlertDitlHdl);
 if (alertId >= 0)
 {
 ModalDialog(NIL, &theItem);
 }
 else
 {
 DrawDialog(theDlogPtr);
 sleep(showTime);
 }
 CloseDialog(theDlogPtr);
 DisposHandle(theAlertDitlHdl);
 }
};
#endif MAC_APPL

/*
 *
 * FindSocketStruct - finds a data structure for a particular socket 
in a linked list
 *
 */
static SockElmntPtrFindSocketStruct(int sock)
{
 register SockElmntPtr  theSockPtr;

 for (theSockPtr = theHeadPtr; theSockPtr != NIL;
   theSockPtr = (SockElmntPtr)theSockPtr->next)
 {
 if (theSockPtr->number == sock)
 {
 errno_MacSocket = noErr;
 return (theSockPtr);
 }
 }
 errno_MacSocket = nonSocket;
 return (NIL);
}

/*
 *
 * OpenTCPDriver - loads and opens UDP-TCP/IP driver (“.IPP”)
 *
 */
static  int OpenTCPDriver()
{
 ParamBlockRec thePB;
 
 thePB.ioParam.ioCompletion = NIL;
 thePB.ioParam.ioNamePtr = (StringPtr)TCPDriverName;
 thePB.ioParam.ioPermssn = fsCurPerm;
 PBOpen(&thePB, Asynchronous);
 PollTCPDriver((TCPiopb *)&thePB);
 if (errno_MacSocket == noErr)
 {
 TCPDriverNotOpened = False;
 ioRefNumTCP = thePB.ioParam.ioRefNum;
 return(1);
 }
 else
 {
 errno_MacSocket = noTCPDriver;
 return(0);
 }
}

#ifdef MAC_APPL
/*
 *
 * OutlineProc - Outlines an item in a dialogbox
 *
 */
static pascal void OutlineProc(WindowPtr thePtr, int theItem)
{
 int    theItemType;
 GrafPtrcurrentPort;
 Handle theItemHdl;
 Rect theBox;

 GetDItem (thePtr, theItem, &theItemType, &theItemHdl, &theBox);
 GetPort(&currentPort);
 SetPort(thePtr);
 PenSize(3, 3);
 InsetRect(&theBox, -4, -4);
 FrameRoundRect (&theBox, 16, 16);
 PenNormal();
 SetPort(currentPort);
};
#endif  MAC_APPL

/*
 *
 * PollTCPDriver - polls the UDP-TCP/IP driver until an action is completed
 *
 */
static  voidPollTCPDriver(TCPiopb *theTCPPtr)
{
 while((errno_MacSocket = theTCPPtr->ioResult) > 0)
 {
 SystemTask();
 }
}

/*
 *
 * RemoveSocketStruct - removes a data structure for a particular socket 
from a
 * linked list
 *
 */
static intRemoveSocketStruct(int sock)
{
 register SockElmntPtr  theSockPtr, thePrevOne = NIL;

 for (theSockPtr = theHeadPtr; theSockPtr != NIL;
   thePrevOne = theSockPtr, theSockPtr = (SockElmntPtr)theSockPtr->next)
 {
 if (theSockPtr->number == sock)
 {
 if (thePrevOne == NIL)
 {
 theHeadPtr = theSockPtr->next;
 }
 else
 {
 thePrevOne->next = theSockPtr->next;
 }
 free(theSockPtr);
 errno_MacSocket = noErr;
 return (1);
 }
 }
 errno_MacSocket = nonSocket;
 return(0);
}

/*
 *
 * SockNotify - prints notification messages for the UDP-TCP/IP driver
 *
 */
static pascal void SockNotify(StreamPtr tcpStream, unsigned short eventCode,
  Ptr userDataPtr, unsigned short terminReason, struct ICMPReport *icmpMsg)
{
 char theErrorMsg[128];
 char *errStrPtr1 = “\0”, *errStrPtr2 = “\0”;
#ifdef  MAC_APPL
 char errNoStr[32];
#endif  MAC_APPL
 
 strcpy(theErrorMsg, “MacSocket: “);
 switch (eventCode)
 {
 case TCPClosing:
 errStrPtr1 = “all data has been received and delivered”;
 break;
 case TCPULPTimeout:
 errStrPtr1 = “time out”;
 break;
 case TCPTerminate:
 errStrPtr1 = “connection terminated, “;
 switch(terminReason)
 {
 case TCPRemoteAbort:
 errStrPtr2 = “connection reset by peer”;
 break;
 case TCPNetworkFailure:
 errStrPtr2 = “network failure”;
 break;
 case TCPSecPrecMismatch:
 errStrPtr2 = “invallid security option or precedence level”;
 break;
 case TCPULPTimeoutTerminate:
 errStrPtr2 = “ULP time out”;
 break;
 case TCPULPAbort:
 errStrPtr2 = “connection aborted”;
 break;
 case TCPULPClose:
 errStrPtr2 = “connection closed gracefully”;
 break;
 case TCPServiceError:
 errStrPtr2 = “unexpected connection initiation segment read”;
 break;
 default:
 errStrPtr2 = “unknown reason”;
 break;
 }
 break;
 case TCPDataArrival:
 errStrPtr1 = “data arrived, no receive outstanding”;
 break;
 case TCPUrgent:
 errStrPtr1 = “urgent data arrived”;
 break;
 case TCPICMPReceived:
 errStrPtr1 = “Internet Control Message arrived”;
 /* still to be printed */
 break;
 default:
 errStrPtr1 = “unknown eventcode”;
 break;
 }
 strcat(theErrorMsg, errStrPtr1);
 strcat(theErrorMsg, errStrPtr2);
#ifndef MAC_APPL
 fprintf(stderr, “%s (%d).\n”, theErrorMsg, eventCode);
#else MAC_APPL
 NumToString(eventCode, errNoStr);
 DoAlert(-1, CtoPstr(theErrorMsg), “\p(“, errNoStr, “\p)”);
#endif  MAC_APPL
};

/**
 **
 ** Global functions
 **
 **/

/**
 **
 ** Functions that substitute relevant UNIX-system calls on the Mac
 **
 **/

/*
 *
 * close_MacSocket - delete a (socket) descriptor if present, else do 
close(int s)
 *
 */
int close_MacSocket(int s)
{
 TCPiopb*theTCPPtr;
 SockElmntPtr  theSockPtr, thePrevPtr = NIL;

 if ((theSockPtr = FindSocketStruct(s)) == NIL)
 {
 return(close(s));
 }
 
 theTCPPtr = &(theSockPtr->thePB);
 theTCPPtr->csCode = TCPClose;
 theTCPPtr->csParam.close.ulpTimeoutValue = CloseTimeout;
 theTCPPtr->csParam.close.ulpTimeoutAction = Abort;
 theTCPPtr->csParam.close.validityFlags = (byte)(timeoutValue | timeoutAction);
 theTCPPtr->csParam.close.userDataPtr = (Ptr)&theUserData;
 PBControl((ParmBlkPtr)theTCPPtr, Asynchronous);
 PollTCPDriver(theTCPPtr);
 theSockPtr->number = -1;
 if (errno_MacSocket == noErr)
 {
 return(0);
 }
 else
 {
 return (-1);
 }
};

/*
 *
 * exit_MacSocket - substitute for exit(int status)
 *
 */
void exit_MacSocket(int status)
{
 ParamBlockRec thePB;

 while (theHeadPtr != NIL)
 {
 shutdown(theHeadPtr->number, 2);
 }
 
 if (!TCPDriverNotOpened)
 {
 thePB.ioParam.ioCompletion = NIL;
 thePB.ioParam.ioRefNum = ioRefNumTCP;
 PBClose(&thePB, Asynchronous);
 /*
 PollTCPDriver(&thePB);
 */
 }
 exit(status);
}

/*
 *
 * perror_MacSocket - substitute for void perror(char *s)
 *
 */
void perror_MacSocket(char *s)
{
 char theErrorMsg[128];
#ifdef  MAC_APPL
 char errNoStr[32];
#endif  MAC_APPL
 
 strcpy(theErrorMsg, s);
 strcat(theErrorMsg, “: “);
 strcat(theErrorMsg, strerror_MacSocket(errno_MacSocket));
#ifndef MAC_APPL
 fprintf(stderr, “%s (%d).\n”, theErrorMsg, errno_MacSocket);
#else MAC_APPL
 NumToString(errno_MacSocket, errNoStr);
 DoAlert(stopIcon, CtoPstr(theErrorMsg), “\p (“, errNoStr, “\p).”);
#endif  MAC_APPL
}

/*
 *
 * strerror_MacSocket - substitute for strerror(int errnum)
 *
 */
char* strerror_MacSocket(int errnum)
{
 char *errStrPtr;
 
 switch (errnum)
 {
 case noTCPDriver:
 errStrPtr = “UDP-TCP/IP driver (\”.IPP\”) not available”;
 break;
 case invalidArgument:
 errStrPtr = “invalid address argument”;
 break;
 case nonSOCK_STREAM:
 errStrPtr = “socket type not supported”;
 break;
 case nonSocket:
 errStrPtr = “invalid socket descriptor”;
 break;
 case nonAF_INET:
 errStrPtr = “domain not supported”;
 break;
 case noBufSpace:
 errStrPtr = “no memory for buffers available”;
 break;
 case ipBadLapErr:
 errStrPtr = “bad network configuration”;
 break;
 case ipBadCnfgErr:
 errStrPtr = “bad IP configuration error”;
 break;
 case ipNoCnfgErr:
 errStrPtr = “missing IP or LAP configuration error”;
 break;
 case ipLoadErr:
 errStrPtr = “error in MacTCP load”;
 break;
 case ipBadAddr:
 errStrPtr = “error in getting address”;
 break;
 case streamAlreadyOpen:
 errStrPtr = “an open stream is already using this receive buffer area”;
 break;
 case invalidLength:
 errStrPtr = “the buffer is too small or too large”;
 break;
 case invalidBufPtr:
 errStrPtr = “illegal buffer pointer”;
 break;
 case insufficientResources:
 errStrPtr = “there are already 64 TCP streams open”;
 break;
 case invalidStreamPtr:
 errStrPtr = “the specified TCP stream is not open”;
 break;
 case connectionExists:
 errStrPtr = “this TCP stream has an open connection”;
 break;
 case duplicateSocket:
 errStrPtr = “a connection already exists on this link”;
 break;
 case commandTimeout:
 errStrPtr =
 “no connection attempt was received in the specified time-out period”;
 break;
 case openFailed:
 errStrPtr = “the connection came halfway up and then failed”;
 break;
 case connectionDoesntExist:
 errStrPtr = “there is no open connection on this stream”;
 break;
 case connectionClosing:
 errStrPtr = “a TCP close command was already issued”;
 break;
 case connectionTerminated:
 errStrPtr = “the connection went down”;
 break;
 case invalidRDS:
 errStrPtr = “trying to release wrong buffer”;
 break;
 default:
 errStrPtr = strerror(errnum);;
 break;
 }
 strcpy(macSocketErrorMssg, errStrPtr);
 return(macSocketErrorMssg);
}

/**
 **
 ** MacSocket calls
 **
 **/

/*
 *
 * connect - initiate a connection on a socket
 *
 */
int connect(int s, struct sockaddr_in *name, int namelen)
{
 TCPiopb*theTCPPtr;
 SockElmntPtr  theSockPtr;
 
 if (namelen != sizeof(struct sockaddr_in))
 {
 errno_MacSocket = invalidArgument;
 return (-1);
 }

 if ((theSockPtr = FindSocketStruct(s)) == NIL)
 {
 return (-1);
 }
 
 theTCPPtr = &(theSockPtr->thePB);
 theTCPPtr->csCode = TCPActiveOpen;
 theTCPPtr->csParam.open.ulpTimeoutValue = ConnectTimeout;
 theTCPPtr->csParam.open.ulpTimeoutAction = Abort;
 theTCPPtr->csParam.open.validityFlags =
 (byte)(timeoutValue | timeoutAction | typeOfService | precedence);
 memcpy((void *)&theTCPPtr->csParam.open.remoteHost, (void *)&name->sin_addr,
 sizeof(name->sin_addr));
 theTCPPtr->csParam.open.remotePort = name->sin_port;
 theTCPPtr->csParam.open.localPort = 0;
 theTCPPtr->csParam.open.tosFlags = (byte)(reliability | lowDelay);
 theTCPPtr->csParam.open.precedence = 0;
 theTCPPtr->csParam.open.dontFrag = False;
 theTCPPtr->csParam.open.timeToLive = (byte)60;
 theTCPPtr->csParam.open.security = False;
 theTCPPtr->csParam.open.optionCnt = (byte)0;
 theTCPPtr->csParam.open.userDataPtr = (Ptr)&theUserData;
 PBControl((ParmBlkPtr)theTCPPtr, Asynchronous);
 PollTCPDriver(theTCPPtr);
 if (errno_MacSocket == noErr)
 {
 return (0);
 }
 else
 {
 return (-1);
 }
};

/*
 *
 * recv - receive a message from a socket
 *
 */
int recv(int s, char *msg, int len, int flags)
{
 TCPiopb*theTCPPtr;
 SockElmntPtr  theSockPtr;
 
 if ((theSockPtr = FindSocketStruct(s)) == NIL)
 {
 return (-1);
 }
 
 theTCPPtr = &(theSockPtr->thePB);
 theTCPPtr->csCode = TCPRcv;
 theTCPPtr->csParam.receive.commandTimeoutValue = RecvTimeout;
 theTCPPtr->csParam.receive.rcvBuff = msg;
 theTCPPtr->csParam.receive.rcvBuffLen = len;
 theTCPPtr->csParam.receive.userDataPtr = (Ptr)&theUserData;
 PBControl((ParmBlkPtr)theTCPPtr, Asynchronous);
 PollTCPDriver(theTCPPtr);
 if (errno_MacSocket == noErr)
 {
 return (theTCPPtr->csParam.receive.rcvBuffLen);
 }
 else
 {
 return (-1);
 }
};

/*
 *
 * recvfrom - receive a message from a socket
 *
 */
int recvfrom(int s, char *msg, int len, int flags, struct sockaddr_in 
*from, int *fromlen)
{
 SockElmntPtr  theSockPtr;
 
 if ((theSockPtr = FindSocketStruct(s)) == NIL)
 {
 errno_MacSocket = invalidStreamPtr;
 return (-1);
 }
 
 if (from != NULL)
 {
 *fromlen = sizeof(from);
 if (!theSockPtr->state & Connected)
 {
 if (!connect(s, from, *fromlen))
 {
 return(-1);
 }
 }
 }
 return(recv(s, msg, len, flags));
};

/*
 *
 * recvmsg - receive a message from a socket
 *
 */
int recvmsg(int s, struct msghdr *msg, int flags)
{
 SockElmntPtr  theSockPtr;
 
 if ((theSockPtr = FindSocketStruct(s)) == NIL)
 {
 errno_MacSocket = invalidStreamPtr;
 return (-1);
 }
 
 if (msg->msg_name != NULL)
 {
 if (!theSockPtr->state & Connected)
 {
 if (!connect(s, (struct sockaddr_in *)msg->msg_name, msg->msg_namelen))
 {
 return(-1);
 }
 }
 }
 return(recv(s, (char *)msg->msg_iov, msg->msg_iovlen, flags));
};

/*
 *
 * send - send a message from a socket
 *
 */
int send(int s, char *msg, int len, int flags)
{
 TCPiopb*theTCPPtr;
 SockElmntPtr  theSockPtr;

 struct theWDS
 {
 short  length;
 Ptr  theDataPtr;
 short  end;
 } theWDS;
 

 if ((theSockPtr = FindSocketStruct(s)) == NIL)
 {
 return (-1);
 }
 theTCPPtr = &(theSockPtr->thePB);
 theTCPPtr->csCode = TCPSend;
 theTCPPtr->csParam.send.ulpTimeoutValue = SendTimeout;
 theTCPPtr->csParam.send.ulpTimeoutAction = True;
 theTCPPtr->csParam.send.validityFlags = (byte)(timeoutValue | timeoutAction);
 theTCPPtr->csParam.send.pushFlag = True; /* May be false ?? */
 theTCPPtr->csParam.send.urgentFlag = False;
 theWDS.length = len;
 theWDS.theDataPtr = msg;
 theWDS.end = 0;
 theTCPPtr->csParam.send.wdsPtr = (Ptr)&theWDS;
 theTCPPtr->csParam.send.userDataPtr = (Ptr)&theUserData;
 PBControl((ParmBlkPtr)theTCPPtr, Asynchronous);
 PollTCPDriver(theTCPPtr);
 if (errno_MacSocket == noErr)
 {
 return(len);
 }
 else
 {
 return (-1);
 }
};

/*
 *
 * sendto - send a message to a socket
 *
 */
int sendto(int s, char *msg, int len, int flags, struct sockaddr_in *to, 
int *tolen)
{
 SockElmntPtr  theSockPtr;
 
 if ((theSockPtr = FindSocketStruct(s)) == NIL)
 {
 errno_MacSocket = invalidStreamPtr;
 return (-1);
 }
 
 if (to != NULL)
 {
 *tolen = sizeof(struct sockaddr_in);
 if (!theSockPtr->state & Connected)
 {
 if (!connect(s, to, *tolen))
 {
 return(-1);
 }
 }
 }
 return(send(s, msg, len, flags));
};

/*
 * sendmsg - send a message to a socket
 */
int sendmsg(int s, struct msghdr *msg, int flags)
{
 SockElmntPtr  theSockPtr;
 
 if ((theSockPtr = FindSocketStruct(s)) == NIL)
 {
 errno_MacSocket = invalidStreamPtr;
 return (-1);
 }
 
 if (msg->msg_name != NULL)
 {
 if (!theSockPtr->state & Connected)
 {
 if (!connect(s, (struct sockaddr_in *)msg->msg_name, msg->msg_namelen))
 {
 return(-1);
 }
 }
 }
 return(send(s, (char *)msg->msg_iov, msg->msg_iovlen, flags));
};

#ifdef  MAC_APPL
/*
 *
 * SetDialogShowTime - sets the time that an MacTCP/IP info DialogBox 
is vissible.
 * when sec <= 0, no message will be displayed.
 *
 */
void SetDialogShowTime(int sec)
{
 showTime = sec;
}
#endif  MAC_APPL

/*
 *
 * shutdown - shut down part of a full-duplex connection
 *
 */
int shutdown(int s, int how)
{
 TCPiopb*theTCPPtr;
 SockElmntPtr  theSockPtr;

 switch (how)
 {
 case 1: /* further sends disalowed */
 return (close_MacSocket(s));
 break;
 case 2: /* further sends and receives disalowed */
 if ((theSockPtr = FindSocketStruct(s)) == NIL)
 {
 return(-1);
 }
 theTCPPtr = &(theSockPtr->thePB);
 theTCPPtr->csCode = TCPRelease;
 PBControl((ParmBlkPtr)theTCPPtr, Asynchronous);
 PollTCPDriver(theTCPPtr);
 return (RemoveSocketStruct(s));
 break;
 case 0: /* further receives disalowed */
 default:
 errno_MacSocket = invalidArgument;
 return(-1);
 break;
 }
};

/*
 * socket - create an endpoint for communication
 */
intsocket(int domain, int type, int protocol)
{
 TCPiopb*theTCPPtr;
 SockElmntPtr  theSockPtr;
 
 if (domain != AF_INET)
 {
 errno_MacSocket = nonAF_INET;
 return (-1);
 }
 if (protocol != 0)
 {
 errno_MacSocket = invalidArgument;
 return (-1);
 }
 if (type != SOCK_STREAM)
 {
 errno_MacSocket = nonSOCK_STREAM;
 return (-1);
 }
 if ((theSockPtr = (SockElmntPtr)CreateSocketStruct()) == NIL)
 {
 errno_MacSocket = noBufSpace;
 return (-1);
 }

 if (TCPDriverNotOpened)
 {
 if (!OpenTCPDriver())
 {
 return(-1);;
 }
 }
 theTCPPtr = &(theSockPtr->thePB);
 theTCPPtr->ioCompletion = NIL;
 theTCPPtr->ioRefNum = ioRefNumTCP;
 theTCPPtr->csCode = TCPCreate;
 theTCPPtr->csParam.create.rcvBuff = theSockPtr->sockBuf;
 theTCPPtr->csParam.create.rcvBuffLen = SockBufSize;
 theTCPPtr->csParam.create.notifyProc = SockNotify;
 theTCPPtr->csParam.create.userDataPtr = (Ptr)&theUserData;
 PBControl((ParmBlkPtr)theTCPPtr, Asynchronous);
 PollTCPDriver(theTCPPtr);
 if (errno_MacSocket == noErr)
 {
 return (theSockPtr->number);
 }
 else
 {
 RemoveSocketStruct(theSockPtr->number);
 return (-1);
 };
}
 
AAPL
$501.11
Apple Inc.
+2.43
MSFT
$34.64
Microsoft Corpora
+0.15
GOOG
$898.03
Google Inc.
+16.02

MacTech Search:
Community Search:

Software Updates via MacUpdate

CrossOver 12.5.1 - Run Windows apps on y...
CrossOver can get your Windows productivity applications and PC games up and running on your Mac quickly and easily. CrossOver runs the Windows software that you need on Mac at home, in the office,... Read more
Paperless 2.3.1 - Digital documents mana...
Paperless is a digital documents manager. Remember when everyone talked about how we would soon be a paperless society? Now it seems like we use paper more than ever. Let's face it - we need and we... Read more
Apple HP Printer Drivers 2.16.1 - For OS...
Apple HP Printer Drivers includes the latest HP printing and scanning software for Mac OS X 10.6, 10.7 and 10.8. For information about supported printer models, see this page.Version 2.16.1: This... Read more
Yep 3.5.1 - Organize and manage all your...
Yep is a document organization and management tool. Like iTunes for music or iPhoto for photos, Yep lets you search and view your documents in a comfortable interface, while offering the ability to... Read more
Apple Canon Laser Printer Drivers 2.11 -...
Apple Canon Laser Printer Drivers is the latest Canon Laser printing and scanning software for Mac OS X 10.6, 10.7 and 10.8. For information about supported printer models, see this page.Version 2.11... Read more
Apple Java for Mac OS X 10.6 Update 17 -...
Apple Java for Mac OS X 10.6 delivers improved security, reliability, and compatibility by updating Java SE 6.Version Update 17: Java for Mac OS X 10.6 Update 17 delivers improved security,... Read more
Arq 3.3 - Online backup (requires Amazon...
Arq is online backup for the Mac using Amazon S3 and Amazon Glacier. It backs-up and faithfully restores all the special metadata of Mac files that other products don't, including resource forks,... Read more
Apple Java 2013-005 - For OS X 10.7 and...
Apple Java for OS X 2013-005 delivers improved security, reliability, and compatibility by updating Java SE 6 to 1.6.0_65. On systems that have not already installed Java for OS X 2012-006, this... Read more
DEVONthink Pro 2.7 - Knowledge base, inf...
Save 10% with our exclusive coupon code: MACUPDATE10 DEVONthink Pro is your essential assistant for today's world, where almost everything is digital. From shopping receipts to important research... Read more
VirtualBox 4.3.0 - x86 virtualization so...
VirtualBox is a family of powerful x86 virtualization products for enterprise as well as home use. Not only is VirtualBox an extremely feature rich, high performance product for enterprise customers... Read more

Briquid Gets Updated with New Undo Butto...
Briquid Gets Updated with New Undo Button, Achievements, and Leaderboards, on Sale for $0.99 Posted by Andrew Stevens on October 16th, 2013 [ | Read more »
Halloween – iLovecraft Brings Frightenin...
Halloween – iLovecraft Brings Frightening Stories From Author H.P. | Read more »
The Blockheads Creator David Frampton Gi...
The Blockheads Creator David Frampton Gives a Postmortem on the Creation Process of the Game Posted by Andrew Stevens on October 16th, 2013 [ permalink ] Hey, a | Read more »
Sorcery! Enhances the Gameplay in Latest...
Sorcery! | Read more »
It Came From Australia: Tiny Death Star
NimbleBit and Disney have teamed up to make Star Wars: Tiny Death Star, a Star Wars take on Tiny Tower. Right now, the game is in testing in Australia (you will never find a more wretched hive of scum and villainy) but we were able to sneak past... | Read more »
FIST OF AWESOME Review
FIST OF AWESOME Review By Rob Rich on October 16th, 2013 Our Rating: :: TALK TO THE FISTUniversal App - Designed for iPhone and iPad A totalitarian society of bears is only the tip of the iceberg in this throwback brawler.   | Read more »
PROVERBidioms Paints English Sayings in...
PROVERBidioms Paints English Sayings in a Picture for Users to Find Posted by Andrew Stevens on October 16th, 2013 [ permalink ] | Read more »
OmniFocus 2 for iPhone Review
OmniFocus 2 for iPhone Review By Carter Dotson on October 16th, 2013 Our Rating: :: OMNIPOTENTiPhone App - Designed for the iPhone, compatible with the iPad OmniFocus 2 for iPhone is a task management app for people who absolutely... | Read more »
Ingress – Google’s Augmented-Reality Gam...
Ingress – Google’s Augmented-Reality Game to Make its Way to iOS Next Year Posted by Andrew Stevens on October 16th, 2013 [ permalink ] | Read more »
CSR Classics is Full of Ridiculously Pre...
CSR Classics is Full of Ridiculously Pretty Classic Automobiles Posted by Rob Rich on October 16th, 2013 [ permalink ] | Read more »

Price Scanner via MacPrices.net

Apple Store Canada offers refurbished 11-inch...
 The Apple Store Canada has Apple Certified Refurbished 2013 11″ MacBook Airs available starting at CDN$ 849. Save up to $180 off the cost of new models. An Apple one-year warranty is included with... Read more
Updated MacBook Price Trackers
We’ve updated our MacBook Price Trackers with the latest information on prices, bundles, and availability on MacBook Airs, MacBook Pros, and the MacBook Pros with Retina Displays from Apple’s... Read more
13-inch Retina MacBook Pros on sale for up to...
B&H Photo has the 13″ 2.5GHz Retina MacBook Pro on sale for $1399 including free shipping. Their price is $100 off MSRP. They have the 13″ 2.6GHz Retina MacBook Pro on sale for $1580 which is $... Read more
AppleCare Protection Plans on sale for up to...
B&H Photo has 3-Year AppleCare Warranties on sale for up to $105 off MSRP including free shipping plus NY sales tax only: - Mac Laptops 15″ and Above: $244 $105 off MSRP - Mac Laptops 13″ and... Read more
Apple’s 64-bit A7 Processor: One Step Closer...
PC Pro’s Darien Graham-Smith reported that Canonical founder and Ubuntu Linux creator Mark Shuttleworth believes Apple intends to follow Ubuntu’s lead and merge its desktop and mobile operating... Read more
MacBook Pro First, Followed By iPad At The En...
French site Info MacG’s Florian Innocente says he has received availability dates and order of arrival for the next MacBook Pro and the iPad from the same contact who had warned hom of the arrival of... Read more
Chart: iPad Value Decline From NextWorth
With every announcement of a new Apple device, serial upgraders begin selling off their previous models – driving down the resale value. So, with the Oct. 22 Apple announcement date approaching,... Read more
SOASTA Survey: What App Do You Check First in...
SOASTA Inc., the leader in cloud and mobile testing announced the results of its recent survey showing which mobile apps are popular with smartphone owners in major American markets. SOASTA’s survey... Read more
Apple, Samsung Reportedly Both Developing 12-...
Digitimes’ Aaron Lee and Joseph Tsai report that Apple and Samsung Electronics are said to both be planning to release 12-inch tablets, and that Apple is currently cooperating with Quanta Computer on... Read more
Apple’s 2011 MacBook Pro Lineup Suffering Fro...
Appleinsider’s Shane Cole says that owners of early-2011 15-inch and 17-inch MacBook Pros are reporting issues with those models’ discrete AMD graphics processors, which in some cases results in the... Read more

Jobs Board

*Apple* Retail - Manager - Apple (United Sta...
Job SummaryKeeping an Apple Store thriving requires a diverse set of leadership skills, and as a Manager, youre a master of them all. In the stores fast-paced, dynamic Read more
*Apple* Support / *Apple* Technician / Mac...
Apple Support / Apple Technician / Mac Support / Mac Set up / Mac TechnicianMac Set up and Apple Support technicianThe person we are looking for will have worked Read more
Senior Mac / *Apple* Systems Engineer - 318...
318 Inc, a top provider of Apple solutions is seeking a new Senior Apple Systems Engineer to be based out of our Santa Monica, California location. We are a Read more
*Apple* Retail - Manager - Apple Inc. (Unite...
Job Summary Keeping an Apple Store thriving requires a diverse set of leadership skills, and as a Manager, you’re a master of them all. In the store’s fast-paced, Read more
*Apple* Solutions Consultant - Apple (United...
**Job Summary** Apple Solutions Consultant (ASC) - Retail Representatives Apple Solutions Consultants are trained by Apple on selling Apple -branded products Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.