auth.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* auth.c -- IOCTLs for authentication -*- linux-c -*-
  2.  * Created: Tue Feb  2 08:37:54 1999 by faith@precisioninsight.com
  3.  *
  4.  * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
  5.  * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
  6.  * All Rights Reserved.
  7.  *
  8.  * Permission is hereby granted, free of charge, to any person obtaining a
  9.  * copy of this software and associated documentation files (the "Software"),
  10.  * to deal in the Software without restriction, including without limitation
  11.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  12.  * and/or sell copies of the Software, and to permit persons to whom the
  13.  * Software is furnished to do so, subject to the following conditions:
  14.  * 
  15.  * The above copyright notice and this permission notice (including the next
  16.  * paragraph) shall be included in all copies or substantial portions of the
  17.  * Software.
  18.  * 
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  20.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  23.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  24.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  25.  * DEALINGS IN THE SOFTWARE.
  26.  *
  27.  * Authors:
  28.  *    Rickard E. (Rik) Faith <faith@valinux.com>
  29.  *
  30.  */
  31. #define __NO_VERSION__
  32. #include "drmP.h"
  33. static int drm_hash_magic(drm_magic_t magic)
  34. {
  35. return magic & (DRM_HASH_SIZE-1);
  36. }
  37. static drm_file_t *drm_find_file(drm_device_t *dev, drm_magic_t magic)
  38. {
  39. drm_file_t   *retval = NULL;
  40. drm_magic_entry_t *pt;
  41. int   hash   = drm_hash_magic(magic);
  42. down(&dev->struct_sem);
  43. for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
  44. if (pt->magic == magic) {
  45. retval = pt->priv;
  46. break;
  47. }
  48. }
  49. up(&dev->struct_sem);
  50. return retval;
  51. }
  52. int drm_add_magic(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
  53. {
  54. int   hash;
  55. drm_magic_entry_t *entry;
  56. DRM_DEBUG("%dn", magic);
  57. hash      = drm_hash_magic(magic);
  58. entry      = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
  59. if (!entry) return -ENOMEM;
  60. entry->magic = magic;
  61. entry->priv  = priv;
  62. entry->next  = NULL;
  63. down(&dev->struct_sem);
  64. if (dev->magiclist[hash].tail) {
  65. dev->magiclist[hash].tail->next = entry;
  66. dev->magiclist[hash].tail = entry;
  67. } else {
  68. dev->magiclist[hash].head = entry;
  69. dev->magiclist[hash].tail = entry;
  70. }
  71. up(&dev->struct_sem);
  72. return 0;
  73. }
  74. int drm_remove_magic(drm_device_t *dev, drm_magic_t magic)
  75. {
  76. drm_magic_entry_t *prev = NULL;
  77. drm_magic_entry_t *pt;
  78. int   hash;
  79. DRM_DEBUG("%dn", magic);
  80. hash = drm_hash_magic(magic);
  81. down(&dev->struct_sem);
  82. for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
  83. if (pt->magic == magic) {
  84. if (dev->magiclist[hash].head == pt) {
  85. dev->magiclist[hash].head = pt->next;
  86. }
  87. if (dev->magiclist[hash].tail == pt) {
  88. dev->magiclist[hash].tail = prev;
  89. }
  90. if (prev) {
  91. prev->next = pt->next;
  92. }
  93. up(&dev->struct_sem);
  94. return 0;
  95. }
  96. }
  97. up(&dev->struct_sem);
  98. drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
  99. return -EINVAL;
  100. }
  101. int drm_getmagic(struct inode *inode, struct file *filp, unsigned int cmd,
  102.  unsigned long arg)
  103. {
  104. static drm_magic_t sequence = 0;
  105. static spinlock_t  lock     = SPIN_LOCK_UNLOCKED;
  106. drm_file_t    *priv    = filp->private_data;
  107. drm_device_t    *dev     = priv->dev;
  108. drm_auth_t    auth;
  109. /* Find unique magic */
  110. if (priv->magic) {
  111. auth.magic = priv->magic;
  112. } else {
  113. do {
  114. spin_lock(&lock);
  115. if (!sequence) ++sequence; /* reserve 0 */
  116. auth.magic = sequence++;
  117. spin_unlock(&lock);
  118. } while (drm_find_file(dev, auth.magic));
  119. priv->magic = auth.magic;
  120. drm_add_magic(dev, priv, auth.magic);
  121. }
  122. DRM_DEBUG("%un", auth.magic);
  123. if (copy_to_user((drm_auth_t *)arg, &auth, sizeof(auth)))
  124. return -EFAULT;
  125. return 0;
  126. }
  127. int drm_authmagic(struct inode *inode, struct file *filp, unsigned int cmd,
  128.   unsigned long arg)
  129. {
  130. drm_file_t    *priv    = filp->private_data;
  131. drm_device_t    *dev     = priv->dev;
  132. drm_auth_t    auth;
  133. drm_file_t    *file;
  134. if (copy_from_user(&auth, (drm_auth_t *)arg, sizeof(auth)))
  135. return -EFAULT;
  136. DRM_DEBUG("%un", auth.magic);
  137. if ((file = drm_find_file(dev, auth.magic))) {
  138. file->authenticated = 1;
  139. drm_remove_magic(dev, auth.magic);
  140. return 0;
  141. }
  142. return -EINVAL;
  143. }