Index: modules/poll/poll.module
===================================================================
--- modules/poll/poll.module
+++ modules/poll/poll.module
@@ -14,6 +14,7 @@ function poll_help($path, $arg) {
   switch ($path) {
     case 'admin/help#poll':
       $output = '<p>' . t('The poll module can be used to create simple polls for site users. A poll is a simple, multiple choice questionnaire which displays the cumulative results of the answers to the poll. Having polls on the site is a good way to receive feedback from community members.') . '</p>';
+      $output = '<p>'. t('The voting is managed using cookies, so different users with same IP (e.g. from the same company) can still vote. If cookies are disabled in a user\'s browser it falls back on IP-based voting.') .'</p>';
       $output .= '<p>' . t('When creating a poll, enter the question being posed, as well as the potential choices (and beginning vote counts for each choice). The status and duration (length of time the poll remains active for new votes) can also be specified. Use the <a href="@poll">poll</a> menu item to view all current polls. To vote in or view the results of a specific poll, click on the poll itself.', array('@poll' => url('poll'))) . '</p>';
       $output .= '<p>' . t('For more information, see the online handbook entry for <a href="@poll">Poll module</a>.', array('@poll' => 'http://drupal.org/handbook/modules/poll/')) . '</p>';
       return $output;
@@ -447,7 +448,18 @@ function poll_load($nodes) {
         $result = db_query('SELECT chid FROM {poll_vote} WHERE nid = :nid AND uid = :uid', array(':nid' => $node->nid, ':uid' => $user->uid))->fetchObject();
       }
       else {
-        $result = db_query("SELECT chid FROM {poll_vote} WHERE nid = :nid AND hostname = :hostname", array(':nid' => $node->nid, ':hostname' => ip_address()))->fetchObject();
+        if (isset($_COOKIE["poll-" . $node->nid])) {
+          $cookie_data = $_COOKIE["poll-" . $node->nid];
+          // Make sure we have a valid IP address in the cookie.
+          if (!preg_match("/^[0-9.\\-]+$/", $cookie_data)) {
+            $result = db_query("SELECT chid FROM {poll_vote} WHERE nid = :nid AND hostname = :hostname", array(':nid' => $node->nid, ':hostname' => ip_address()))->fetchObject();
+          }
+          else {
+            $result = db_query("SELECT chid FROM {poll_vote} WHERE nid = :nid AND hostname = :hostname", array(':nid' => $node->nid, ':hostname' => $cookie_data))->fetchObject();
+          }
+        }
+        else {
+          $result = db_query("SELECT chid FROM {poll_vote} WHERE nid = :nid AND hostname = :hostname", array(':nid' => $node->nid, ':hostname' => ip_address()))->fetchObject();
+        }
       }
       if ($result) {
         $poll->vote = $result->chid;
@@ -455,6 +467,10 @@ function poll_load($nodes) {
       else {
         $poll->vote = -1;
         $poll->allowvotes = TRUE;
+        if (!isset($_COOKIE["poll-".$node->nid])) {
+          $cookie_data = ip_address().'-'.rand();
+          setcookie("poll-".$node->nid, (string) $cookie_data, (time()+60*60*24*365), "/");
+        }
       }
     }
     foreach ($poll as $key => $value) {
@@ -679,14 +695,46 @@ function poll_vote($form, &$form_state) 
   $choice = $form_state['values']['choice'];
 
   global $user;
-  db_insert('poll_vote')
-    ->fields(array(
-      'nid' => $node->nid,
-      'chid' => $choice,
-      'uid' => $user->uid,
-      'hostname' => $user->uid ? ip_address() : '',
-    ))
-    ->execute();
+  // Logged in user.
+  if ($user->uid) {
+    db_insert('poll_vote')
+      ->fields(array(
+        'nid' => $node->nid,
+        'chid' => $choice,
+        'uid' => $user->uid,
+        'hostname' => ip_address(),
+      ))
+      ->execute();
+  }
+  else {
+    // Anonymous, check for cookies.
+    if (isset($_COOKIE["poll-".$node->nid])) {
+      $cookie_data = $_COOKIE["poll-".$node->nid];
+      if (!preg_match("/^[0-9.\\-]+$/", $cookie_data)) {
+        drupal_set_message(t('Your vote was not recorded.'));
+        return;
+      }
+      db_insert('poll_vote')
+        ->fields(array(
+          'nid' => $node->nid,
+          'chid' => $choice,
+          'uid' => $user->uid,
+          'hostname' => $cookie_data,
+        ))
+        ->execute();
+    }
+    // Anonymous, no cookies, use IP address.
+    else {
+      db_insert('poll_vote')
+        ->fields(array(
+          'nid' => $node->nid,
+          'chid' => $choice,
+          'uid' => $user->uid,
+          'hostname' => ip_address(),
+        ))
+        ->execute();
+    }
+  }
 
   // Add one to the votes.
   db_update('poll_choice')
@@ -873,6 +921,11 @@ function poll_cancel($form, &$form_state
     ->expression('chvotes', 'chvotes - 1')
     ->condition('chid', $node->vote)
     ->execute();
+  
+  // Vote canceled, delete any poll cookies.
+  if (isset($_COOKIE["poll-" . $node->nid])) {
+    setcookie("poll-" . $node->nid, "", time() - 3600, "/");
+  }
 
   drupal_set_message(t('Your vote was cancelled.'));
 }
