Monday, May 30, 2011

Android Progress Dialog Example

In situations when you need to wait some operation it is good practice to notify user that operation is in progress.For this cases in Android present several classes which can help with this. One of them I am going to demonstrate.

In this tutorial, I will show you how to add a progress dialog to your Android application. A dialog is usually a small window or tab that appears before any activity in your application. It is intended to display alerts or information to the user. A progress dialog can be used to either show some processing activity to the user or to show the progress of some custom activity using the progress bar.

To create a Progress Dialog, we can make use of the ProgressDialog class which is an extension of the AlertDialog class. It can be used to display a standard progress dialog with a spinning wheel and some custom text. You can display your Progress Dialog using a simple show () call on your dialog object.

Here's the syntax to create a standard Progress dialog:
ProgressDialog MyDialog = MyActivity.this, "TITLE " , " Loading. Please wait ... ", true);
It has four parameters:
1. The application context
2. The title of the Dialog
3. The Dialog Text or Message which is displayed in the dialog
4. A boolean value indicating whether the progress is indeterminate

and to disapper the ProgressDialog you have to add dismiss() like this:

Now I will show how to use ProgressDialog class for showing progress dialog. I will show how to create progress dialog with title and without title.

With TItle:, "In progress", "Loading");

What if I you want to hide the title? just put empty string as title parameter., "", "Loading...");


//in the class...
private ProgressDialog progressBar;

//when you want the dialog to show the first time.
progressBar =, "Disconnecting", "Please wait for few secs...");

//when you want the progressbar to disappear
if (progressBar.isShowing()) {

Friday, May 27, 2011

Error: Unable to open class file and How to fix it.

[2011-05-27 12:12:39 - listActivity] ERROR: Unable to open class file /root/workspace/ No such file or directory

[2011-05-27 13:50:38 - listActivity] ERROR: Unable to open class file /root/workspace// No such file or directory and is a automatically generated file.

The ADT has a few such annoying bugs. But you can sort them out..
What usually helps is:

1. Close Project->Open Project > Build Automatically .
2.Another thing that sometimes helps is right click project > android tools > fix project properties and remove unnecessary content or jar files.

3.Or you can do Project->clean and Refresh .

If still it not generating files then check your class there must be a extra line..

Import*; Remove that and then do all the above one by one..

Hope it help ..

If someone know other way please let me know.



Tuesday, May 24, 2011

Conversion to Dalvik format failed with error 1

Sometime You will encounter this problem when trying to Build Android Project on Eclipse..
 You will get such output in console:

[2011-05-24 09:25:03 - Android C2DM] Dx 1 error; aborting
[2011-05-24 09:25:03 - Android C2DM] Conversion to Dalvik format failed with error 1

You can solve this problem:

Go to Project » Properties » Java Build Path » Libraries and remove all except the "Android X.Y" (in my case Android 2.2). click OK. 
and then
Go to Project » Clean » Clean projects selected below » select your project and click OK.

 That work for me. Hope it works for you too.!!!!

Tuesday, May 17, 2011

Third Party Applcation Server

The Third Party Server is *your* server and can actually be any process written in any language (for example, it can be a batch process or a cron script). The role of the 3rd party "server" is to send the message to the device.

The Server will store (or update) the registrationID received into its local database. So, eventually the server will have registrationIDs from the devices.
Your server needs to get a ClientLogin Auth token in order to talk to the C2DM servers. When it wants to push a message to the device.
For ClientLogin Auth_Token: Click Here

To send a message to a particular device, the Server needs to POST to the C2DM Service the following 4 things:
  1.  The accountName which will be .
  2. An authentication Token.
  3. The registrationID of the device it wants to send the message. 
  4. The message itself (Message limit 1024 Bytes)


// Create a new HttpClient and Post Header 
HttpClient httpclient = new DefaultHttpClient(); 
HttpPost httppost = new HttpPost(""); 

//Your Authorization Token
httppost.addHeader("Authorization", "GoogleLogin auth="+authToken); 
// Add your data 
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); 
nameValuePairs.add(new BasicNameValuePair("registration_id",regId)); 
nameValuePairs.add(new BasicNameValuePair("collapse_key", "TEST")); 

//.<message> is the key and Message is "Push Contact"
nameValuePairs.add(new BasicNameValuePair("data.message","Push Contact")); 
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,"UTF-8")); 

// Execute HTTP Post Request 
System.out.println("Executing  sendMessage"); 
HttpResponse response = httpclient.execute(httppost); 
if (response.getEntity() != null) 

This code work properly on Apache Tomcat Server but while deploying this code on the Google App Engine you will get the Restricted class issues..So if you are thinking of deploying on Google App Engine Try this...

// Send a sync message to this Android device.

URL url = new URL("");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestProperty("Authorization", "GoogleLogin auth="+Constants.authToken); 
urlConnection.setRequestProperty("Accept", "text/html, */*");
urlConnection.setRequestProperty("Connection", "keep-alive");

//Send MEssage
StringBuilder postDataBuilder = new StringBuilder();
postDataBuilder.append("registration_id"). append("=").append("YOUR_REGISTRATION_ID");
byte[] postData = postDataBuilder.toString().getBytes(URLEncoder.encode("UTF-8"));

//Executing  sendMessage
OutputStream outputStream = urlConnection.getOutputStream();

int responseCode = urlConnection.getResponseCode();

If you like this post..Please do comments..


Wednesday, May 11, 2011

Software Release life cycle

Life Cycle of Software Release:
A software release lifecycle consists of different stages that report the stability of a piece of program and the amount of development is necessary before the final release. It is the distribution of software code, documentation, and support materials and composed of discrete phases that describe the software's maturity as it advances from planning and development to release and support phases.
Each version of a product goes through a stage when new features are added, or the alpha stage, a stage that is being actively debugged, or the beta stage, and finally a stage in which all major errors have been removed, or the stable phase. Intermediate stages may even be recognized. The stages can be formally announced and regulated by the developers of the project, but sometimes the terms are used informally to report the status of a product.

Pre-alpha refers to all activities performed during the software project prior to testing. These activities can include requirement analysis, software design, software development and unit testing.

The alpha phase of the release life cycle is the first phase to begin software testing (alpha is the first letter of the ancient Greek alphabet, used as the number 1). In this phase, developers generally test the software using white box technique. Additional validation is then performed using black box or gray box techniques, by another testing team. Moving to black box testing inside the organization is known as alpha release.Alpha software can be unstable and could cause crashes or data loss. The exception to this is when the alpha is available publicly (such as a pre-order bonus), in which developers normally push for stability so that their testers can test properly. External availability of alpha software is uncommon.

Beta is the software development phase following alpha (beta is the second letter of the ancient Greek alphabet, used as the number 2. It is not nowadays usual to speak of a later gamma test). It generally begins when the software is feature complete. The focus of beta testing is reducing impacts to users, often incorporating usability testing. The process of delivering a beta version to the users is called beta release and this is typically the first time that the software is available outside of the organization that developed it.The users of a beta version are called beta testers. They are usually customers or prospective customers of the organization that develops the software, willing to test the software without charge, often receiving the final software free of charge or for a reduced price.
Beta version software is often useful for demonstrations and previews within an organisation and to prospective customers. Some developers refer to this stage as a preview, prototype, technical preview (TP), or early access.

Release candidate:
The term release candidate (RC) refers to a version with potential to be a final product, which is ready to release unless fatal bugs emerge. In this stage of product stabilization, all product features have been designed, coded and tested through one or more beta cycles with no known showstopper-class bug.
Other Greek letters, such as gamma and delta, are sometimes used to indicate versions that are substantially complete, but still undergoing testing, with omega or zenith used to indicate final testing versions that are believed to be relatively bug-free, ready for production.
A release is called code complete when the development team agrees that no entirely new source code will be added to this release. There may still be source code changes to fix defects. There may still be changes to documentation and data files, and to the code for test cases or utilities. New code may be added in a future release.

The term "release to manufacturing" or "release to marketing" (both abbreviated RTM, initials also commonly used for the quite different "return to manufacturer" of faulty goods)—also known as "going gold"—is a term used when software is ready for or has been delivered or provided to the customer. It is typically used in certain retail mass-production software contexts—as opposed to a specialized software production or project in a commercial or government production and distribution—where the software is sold as part of a bundle in a related computer hardware sale and typically where the software and related hardware is ultimately to be available and sold on mass/public basis at retail stores to indicate that the software has met a defined quality level and is ready for mass retail distribution. RTM could also mean in other contexts that the software has been delivered or released to a client or customer for installation or distribution to the related hardware end user computers or machines. The term does not define the delivery mechanism or volume; it only states that the quality is sufficient for mass distribution.

General availability:
General availability or general acceptance (GA) is the point where all necessary commercialization activities have been completed and the software has been made available to the general market either via the web or physical media.

Google App Engine - Restrictions

Google offers a cloud computing infrastructure called Google App Engine (App Engine) for creating and running web Applications. App Engine allows the dynamic allocation of system resources for an application based on the actual demand. Currently App Engine supports Python and Java based applications.

But Google App engine have some Restrictions
GoogleApp Engine runs a version of Java 6 but does not provide all Java classes, for example Swing and most AWT classes are not supported.
You cannot use Threads or frameworks which uses Threads. You can also not write to the filesystem and only read files which are part of your application. Certain "java.lang.System" actions, e.g. gc() or exit() will do nothing. You can not call JNI code. Reflection is possible for your own classes and standard Java classes but your cannot use reflection to access other classes outside your application.
A servlet needs also to reply within 30 seconds otherwise a" is thrown.

ClientLogin for Installed Applications for C2DM - Tutorial

Before you can write client applications that use the C2DM feature, you must have an HTTPS application server that meets the following criteria:Able to communicate with your client.
  • Able to fire off HTTP requests to the C2DM server.
  • Able to handle requests and queue data as needed. For example, it should be able to perform exponential back off.
  •  Able to store the ClientLogin Auth token and client registration IDs. The ClientLogin Auth token is included in the header of POST requests that send messages. For more discussion of this topic, see ClientLogin for Installed Applications. The server should store the token and have a policy to refresh it periodically.

The ClientLogin authorization process:
Authorization with ClientLogin involves a sequence of interactions between three entities: the installed application, Google services, and the user. This diagram illustrates the sequence:

  1. When the third-party application needs to access a user's Google service, it retrieves the user's login name and password.
  2. The third-party application then makes a ClientLogin call to Google's Authorization service.
  3. If the Google Authorization service decides additional vetting is necessary, it returns failure response with a CAPTCHA token and challenge, in the form of a URL for a CAPTCHA image. 
  4. If a CAPTCHA challenge is received, the third-party application displays the CAPTCHA image for the user and solicits an answer from the user. 
  5. If requested, the user submits an answer to the CAPTCHA challenge. 
  6. The third-party application makes a new ClientLogin call, this time including the CAPTCHA answer and token (received with the failure response). 
  7. On a successful login attempt (with or without CAPTCHA challenge), the Google Authorization service returns a token to the application. 
  8. The application contacts the Google service with a request for data access, referencing the token received from the Google Authorization service. 
  9. If the Google service recognizes the token, it supplies the requested data access.

How the Application Server Sends Messages

This section describes how the third-party application server sends messages to a 3rd party client application running on a mobile device.
Before the third-party application server can send a message to an application, it must have received a registration ID from it.
To send a message, the application server issues a POST request to that includes the following:
registration_idThe registration ID retrieved from the Android application on the phone. Required.
collapse_keyAn arbitrary string that is used to collapse a group of like messages when the device is offline, so that only the last message gets sent to the client. This is intended to avoid sending too many messages to the phone when it comes back online. Note that since there is no guarantee of the order in which messages get sent, the "last" message may not actually be the last message sent by the application server. Required.
Payload data, expressed as key-value pairs. If present, it will be included in the Intent as application data, with the <key>. There is no limit on the number of key/value pairs, though there is a limit on the total size of the message. Optional.
delay_while_idleIf included, indicates that the message should not be sent immediately if the device is idle. The server will wait for the device to become active, and then only the last message for each collapse_key value will be sent. Optional.
Authorization: GoogleLogin auth=[AUTH_TOKEN]Header with a ClientLogin Auth token. The cookie must be associated with the ac2dm service. Required.

This table lists the possible response codes:
Includes body containing:
  • id=[ID of sent message]
  • Error=[error code]
    • QuotaExceeded — Too many messages sent by the sender. Retry after a while.
    • DeviceQuotaExceeded — Too many messages sent by the sender to a specific device. Retry after a while.
    • InvalidRegistration — Missing or bad registration_id. Sender should stop sending messages to this device.
    • NotRegistered — The registration_id is no longer valid, for example user has uninstalled the application or turned off notifications. Sender should stop sending messages to this device.
    • MessageTooBig — The payload of the message is too big, see the limitations. Reduce the size of the message.
    • MissingCollapseKey — Collapse key is required. Include collapse key in the request.
503Indicates that the server is temporarily unavailable (i.e., because of timeouts, etc ). Sender must retry later, honoring any Retry-After header included in the response. Application servers must implement exponential back off. Senders that create problems risk being blacklisted.
401Indicates that the ClientLogin AUTH_TOKEN used to validate the sender is invalid


// Create a new HttpClient and Post Header 
HttpClient httpclient = new DefaultHttpClient(); 
HttpPost httppost = new HttpPost(""); 
// this is for proxy settings 

HttpParams params = httpclient.getParams(); 
params.setParameter("content-type", "application/x-www-form-urlencoded"); 
try { 
           // Add your data 
           List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); 
           nameValuePairs.add(new BasicNameValuePair("accountType","HOSTED_OR_GOOGLE")); 
           nameValuePairs.add(new BasicNameValuePair("Email","ar*****")); 
           nameValuePairs.add(new BasicNameValuePair("Passwd","W******21")); 
           nameValuePairs.add(new BasicNameValuePair("service", "ac2dm")); 
           nameValuePairs.add(new BasicNameValuePair("source",   "arxxus.push.1.1")); 
           httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); 
           // Execute HTTP Post Requestu 
           HttpResponse response = httpclient.execute(httppost); 
          BufferedReader in = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 
          StringBuffer sb = new StringBuffer(""); 
          String line = ""; 
          while ((line = in.readLine()) != null) 
         String result = sb.toString(); 
         String authToken=result.substring(result.indexOf("Auth=")+5); 


This code work properly on Apache Tomcat Server but while deploying this code on the Google App Engine you will get the Restricted class issues..So if you are thinking of deploying on Google App Engine Try this...

HttpURLConnection urlConnection;
URL url = new URL("");
urlConnection = (HttpURLConnection) url.openConnection();
StringBuilder content = new StringBuilder();
content.append("&source=").append( "arxxus.push.1.1");
OutputStream outputStream = urlConnection.getOutputStream();
int responseCode = urlConnection.getResponseCode();
StringBuffer resp = new StringBuffer(); 
if (responseCode == HttpURLConnection.HTTP_OK) 
   InputStream inputStream = urlConnection.getInputStream();
     BufferedReader rd = new BufferedReader(new InputStreamReader(inputStream));
     String line; 
     while ((line = rd.readLine()) != null) 
String authToken=resp.toString();

If you like this post..Please do comments..

Tuesday, May 10, 2011

Android Cloud to Device Messaging(C2DM) Tutorial

This tutorial is for getting started with Android Cloud to Device Messaging (C2DM) on Android. In the iOS world it is knows as “push notifications”.

This feature will definitely help developers and their apps to streamline and optimize the data transfers. This would mean that apps now do not have to poll their servers at regular intervals to check for updates. The servers will be able to send updates (like Push Notifications) to the devices and makes it easier for mobile applications to sync data with servers.

There are many different ways of accomplishing the same thing(polling,constant server connections,SMS messages).

C2DM Alternatives:

Polling: The application itself would periodically poll your servers to check for new messages. You would need to implement everything from queuing messages to writing the polling code. Alerts are no good if they’re delayed due to a low polling period but the more frequently you poll, the more the battery is going to die.

SMS: Android can intercept SMS messages and you could include a payload to tell the application what to do. But then why not just use SMS in the first place? SMS is costly.

Persistent Connection: This would solve the problem of periodic polling but would destroy the battery life.

Cloud to device messaging 

“Android Cloud to Device Messaging (C2DM) is a service that helps developers send data from servers to their applications on Android devices. The service provides a simple, lightweight mechanism that servers can use to tell mobile applications to contact the server directly, to fetch updated application or user data. The C2DM service handles all aspects of queueing of messages and delivery to the target application running on the target device.”

It is a server push service provided by Google so that 3rd party applications can push messages to their applications on android devices.
Here are a few basic things to know about C2DM:
  1. It requires Android 2.2; C2DM uses Google services which are present on any device running the Android Market. 
  2. It uses existing connections for Google services. This requires the users to sign into their Google account on Android. 
  3. It allows 3rd party servers to send lightweight data messages to their apps. The C2DM service is not designed for pushing a lot of user content; rather it should be used like a “tickle”, to tell the app that there is new data on the server, so the app can fetch it. 
  4. An application doesn’t need to be running to receive data messages. The system will wake up the app via an Intent broadcast when the the data message arrives, so long as the app is set up with the proper Intent Receiver and permissions. 
  5. No user interface is required for receiving the data messages. The app can post a notification (or display other UI) if it desires.
Here is how it works:

To enable C2DM, an application on the device registers with Google and get a registration ID, and sends the ID to its server.

An Android application needs to register with C2DM servers before receiving any message. To register it needs to send an Intent (, with 2 extra parameters:
  • sender is the ID of the account authorized to send messages to the application, typically the email address of an account set up by the application's developer.
  • app is the application's ID, set with a PendingIntent to allow the registration service to extract application information.
For example:
Intent registrationIntent = new Intent("");
registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0)); // boilerplate
registrationIntent.putExtra("sender", emailOfSender);

The C2DM servers route the message to the device, and an Intent broadcast is sent to the app.

// Registration ID received via an Intent
public void onReceive(Context context, Intent intent) {
  String action = intent.getAction();
  if (“”.equals(action)) {
    handleRegistration(context, intent);
public void handleRegistration(Context context, Intent intent) {
  String id = intent.getExtra(“registration_id”);
  if ((intent.getExtra(“error”) != null) {
    // Registration failed.  Try again later, with backoff.
  } else if (id != null) {
    // Send the registration ID to the app’s server.
    // Be sure to do this in a separate thread.
The app can unregister with C2DM when the user no longer wants messages to be pushed to it.
Intent unregIntent = new Intent("");
unregIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));

Friday, May 6, 2011

IPC:Shared Memory

Shared Memory

Shared Memory is an efficeint means of passing data between programs. One program will create a memory portion which other processes (if permitted) can access.

In the Solaris 2.x operating system, the most efficient way to implement shared memory applications is to rely on the mmap() function and on the system's native virtual memory facility. Solaris 2.x also supports System V shared memory, which is another way to let multiple processes attach a segment of physical memory to their virtual address spaces. When write access is allowed for more than one process, an outside protocol or mechanism such as a semaphore can be used to prevent inconsistencies and collisions.

A process creates a shared memory segment using shmget()|. The original owner of a shared memory segment can assign ownership to another user with shmctl(). It can also revoke this assignment. Other processes with proper permission can perform various control functions on the shared memory segment using shmctl(). Once created, a shared segment can be attached to a process address space using shmat(). It can be detached using shmdt() (see shmop()). The attaching process must have the appropriate permissions for shmat(). Once attached, the process can read or write to the segment, as allowed by the permission requested in the attach operation. A shared segment can be attached multiple times by the same process. A shared memory segment is described by a control structure with a unique ID that points to an area of physical memory. The identifier of the segment is called the shmid. The structure definition for the shared memory segment control structures and prototypews can be found in .

Accessing a Shared Memory Segment

shmget() is used to obtain access to a shared memory segment. It is prottyped by:

int shmget(key_t key, size_t size, int shmflg);
The key argument is a access value associated with the semaphore ID. The size argument is the size in bytes of the requested shared memory. The shmflg argument specifies the initial access permissions and creation control flags.

When the call succeeds, it returns the shared memory segment ID. This call is also used to get the ID of an existing shared segment (from a process requesting sharing of some existing memory portion).

The following code illustrates shmget():



key_t key; /* key to be passed to shmget() */
int shmflg; /* shmflg to be passed to shmget() */
int shmid; /* return value from shmget() */
int size; /* size to be passed to shmget() */


key = ...
size = ...
shmflg) = ...

if ((shmid = shmget (key, size, shmflg)) == -1) {
perror("shmget: shmget failed"); exit(1); } else {
(void) fprintf(stderr, "shmget: shmget returned %d\n", shmid);
Controlling a Shared Memory Segment

shmctl() is used to alter the permissions and other characteristics of a shared memory segment. It is prototyped as follows:

int shmctl(int shmid, int cmd, struct shmid_ds *buf);
The process must have an effective shmid of owner, creator or superuser to perform this command. The cmd argument is one of following control commands:

-- Lock the specified shared memory segment in memory. The process must have the effective ID of superuser to perform this command.
-- Unlock the shared memory segment. The process must have the effective ID of superuser to perform this command.
-- Return the status information contained in the control structure and place it in the buffer pointed to by buf. The process must have read permission on the segment to perform this command.
-- Set the effective user and group identification and access permissions. The process must have an effective ID of owner, creator or superuser to perform this command.
-- Remove the shared memory segment.
The buf is a sructure of type struct shmid_ds which is defined in

The following code illustrates shmctl():



int cmd; /* command code for shmctl() */
int shmid; /* segment ID */
struct shmid_ds shmid_ds; /* shared memory data structure to
hold results */

shmid = ...
cmd = ...
if ((rtrn = shmctl(shmid, cmd, shmid_ds)) == -1) {
perror("shmctl: shmctl failed");
Attaching and Detaching a Shared Memory Segment

shmat() and shmdt() are used to attach and detach shared memory segments. They are prototypes as follows:

void *shmat(int shmid, const void *shmaddr, int shmflg);

int shmdt(const void *shmaddr);
shmat() returns a pointer, shmaddr, to the head of the shared segment associated with a valid shmid. shmdt() detaches the shared memory segment located at the address indicated by shmaddr

. The following code illustrates calls to shmat() and shmdt():


static struct state { /* Internal record of attached segments. */
int shmid; /* shmid of attached segment */
char *shmaddr; /* attach point */
int shmflg; /* flags used on attach */
} ap[MAXnap]; /* State of current attached segments. */
int nap; /* Number of currently attached segments. */


char *addr; /* address work variable */
register int i; /* work area */
register struct state *p; /* ptr to current state entry */

p = &ap[nap++];
p->shmid = ...
p->shmaddr = ...
p->shmflg = ...

p->shmaddr = shmat(p->shmid, p->shmaddr, p->shmflg);
if(p->shmaddr == (char *)-1) {
perror("shmop: shmat failed");
} else
(void) fprintf(stderr, "shmop: shmat returned %#8.8x\n",

i = shmdt(addr);
if(i == -1) {
perror("shmop: shmdt failed");
} else {
(void) fprintf(stderr, "shmop: shmdt returned %d\n", i);

for (p = ap, i = nap; i--; p++)
if (p->shmaddr == addr) *p = ap[--nap];

Example two processes comunicating via shared memory: shm_server.c, shm_client.c

We develop two programs here that illustrate the passing of a simple piece of memery (a string) between the processes if running simulatenously:

-- simply creates the string and shared memory portion.
-- attaches itself to the created shared memory portion and uses the string (printf.
The code listings of the 2 programs no follow:



#define SHMSZ 27

char c;
int shmid;
key_t key;
char *shm, *s;

* We'll name our shared memory segment
* "5678".
key = 5678;

* Create the segment.
if ((shmid = shmget(key, SHMSZ, IPC_CREAT | 0666)) < 0) {

* Now we attach the segment to our data space.
if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {

* Now put some things into the memory for the
* other process to read.
s = shm;

for (c = 'a'; c <= 'z'; c++)
*s++ = c;
*s = NULL;

* Finally, we wait until the other process
* changes the first character of our memory
* to '*', indicating that it has read what
* we put there.
while (*shm != '*')


* shm-client - client program to demonstrate shared memory.

#define SHMSZ 27

int shmid;
key_t key;
char *shm, *s;

* We need to get the segment named
* "5678", created by the server.
key = 5678;

* Locate the segment.
if ((shmid = shmget(key, SHMSZ, 0666)) < 0) {

* Now we attach the segment to our data space.
if ((shm = shmat(shmid, NULL, 0)) == (char *) -1) {

* Now read what the server put in the memory.
for (s = shm; *s != NULL; s++)

* Finally, change the first character of the
* segment to '*', indicating we have read
* the segment.
*shm = '*';