aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/netmisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/netmisc.c')
-rw-r--r--fs/cifs/netmisc.c171
1 files changed, 56 insertions, 115 deletions
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 53e304d59544..2bfed3f45d0f 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -3,23 +3,22 @@
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2002 4 * Copyright (c) International Business Machines Corp., 2002
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * Error mapping routines from Samba libsmb/errormap.c 7 * Error mapping routines from Samba libsmb/errormap.c
8 * Copyright (C) Andrew Tridgell 2001 8 * Copyright (C) Andrew Tridgell 2001
9 * 9 *
10 *
11 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 12 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version. 13 * (at your option) any later version.
15 * 14 *
16 * This program is distributed in the hope that it will be useful, 15 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
19 * the GNU General Public License for more details. 18 * the GNU General Public License for more details.
20 * 19 *
21 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */ 23 */
25 24
@@ -30,9 +29,7 @@
30#include <linux/fs.h> 29#include <linux/fs.h>
31#include <asm/div64.h> 30#include <asm/div64.h>
32#include <asm/byteorder.h> 31#include <asm/byteorder.h>
33#ifdef CONFIG_CIFS_EXPERIMENTAL
34#include <linux/inet.h> 32#include <linux/inet.h>
35#endif
36#include "cifsfs.h" 33#include "cifsfs.h"
37#include "cifspdu.h" 34#include "cifspdu.h"
38#include "cifsglob.h" 35#include "cifsglob.h"
@@ -67,22 +64,22 @@ static const struct smb_to_posix_error mapping_table_ERRDOS[] = {
67 {ERRbadshare, -ETXTBSY}, 64 {ERRbadshare, -ETXTBSY},
68 {ERRlock, -EACCES}, 65 {ERRlock, -EACCES},
69 {ERRunsup, -EINVAL}, 66 {ERRunsup, -EINVAL},
70 {ERRnosuchshare,-ENXIO}, 67 {ERRnosuchshare, -ENXIO},
71 {ERRfilexists, -EEXIST}, 68 {ERRfilexists, -EEXIST},
72 {ERRinvparm, -EINVAL}, 69 {ERRinvparm, -EINVAL},
73 {ERRdiskfull, -ENOSPC}, 70 {ERRdiskfull, -ENOSPC},
74 {ERRinvname, -ENOENT}, 71 {ERRinvname, -ENOENT},
75 {ERRinvlevel,-EOPNOTSUPP}, 72 {ERRinvlevel, -EOPNOTSUPP},
76 {ERRdirnotempty, -ENOTEMPTY}, 73 {ERRdirnotempty, -ENOTEMPTY},
77 {ERRnotlocked, -ENOLCK}, 74 {ERRnotlocked, -ENOLCK},
78 {ERRcancelviolation, -ENOLCK}, 75 {ERRcancelviolation, -ENOLCK},
79 {ERRalreadyexists, -EEXIST}, 76 {ERRalreadyexists, -EEXIST},
80 {ERRmoredata, -EOVERFLOW}, 77 {ERRmoredata, -EOVERFLOW},
81 {ERReasnotsupported,-EOPNOTSUPP}, 78 {ERReasnotsupported, -EOPNOTSUPP},
82 {ErrQuota, -EDQUOT}, 79 {ErrQuota, -EDQUOT},
83 {ErrNotALink, -ENOLINK}, 80 {ErrNotALink, -ENOLINK},
84 {ERRnetlogonNotStarted,-ENOPROTOOPT}, 81 {ERRnetlogonNotStarted, -ENOPROTOOPT},
85 {ErrTooManyLinks,-EMLINK}, 82 {ErrTooManyLinks, -EMLINK},
86 {0, 0} 83 {0, 0}
87}; 84};
88 85
@@ -133,85 +130,24 @@ static const struct smb_to_posix_error mapping_table_ERRHRD[] = {
133/* returns 0 if invalid address */ 130/* returns 0 if invalid address */
134 131
135int 132int
136cifs_inet_pton(int address_family, char *cp,void *dst) 133cifs_inet_pton(int address_family, char *cp, void *dst)
137{ 134{
138#ifdef CONFIG_CIFS_EXPERIMENTAL
139 int ret = 0; 135 int ret = 0;
140 136
141 /* calculate length by finding first slash or NULL */ 137 /* calculate length by finding first slash or NULL */
142 /* BB Should we convert '/' slash to '\' here since it seems already done 138 /* BB Should we convert '/' slash to '\' here since it seems already
143 before this */ 139 * done before this */
144 if( address_family == AF_INET ){ 140 if ( address_family == AF_INET ) {
145 ret = in4_pton(cp, -1 /* len */, dst , '\\', NULL); 141 ret = in4_pton(cp, -1 /* len */, dst , '\\', NULL);
146 } else if( address_family == AF_INET6 ){ 142 } else if ( address_family == AF_INET6 ) {
147 ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL); 143 ret = in6_pton(cp, -1 /* len */, dst , '\\', NULL);
148 } 144 }
149#ifdef CONFIG_CIFS_DEBUG2 145#ifdef CONFIG_CIFS_DEBUG2
150 cFYI(1,("address conversion returned %d for %s", ret, cp)); 146 cFYI(1, ("address conversion returned %d for %s", ret, cp));
151#endif 147#endif
152 if (ret > 0) 148 if (ret > 0)
153 ret = 1; 149 ret = 1;
154 return ret; 150 return ret;
155#else
156 int value;
157 int digit;
158 int i;
159 char temp;
160 char bytes[4];
161 char *end = bytes;
162 static const int addr_class_max[4] =
163 { 0xffffffff, 0xffffff, 0xffff, 0xff };
164
165 if(address_family != AF_INET)
166 return -EAFNOSUPPORT;
167
168 for (i = 0; i < 4; i++) {
169 bytes[i] = 0;
170 }
171
172 temp = *cp;
173
174 while (TRUE) {
175 if (!isdigit(temp))
176 return 0;
177
178 value = 0;
179 digit = 0;
180 for (;;) {
181 if (isascii(temp) && isdigit(temp)) {
182 value = (value * 10) + temp - '0';
183 temp = *++cp;
184 digit = 1;
185 } else
186 break;
187 }
188
189 if (temp == '.') {
190 if ((end > bytes + 2) || (value > 255))
191 return 0;
192 *end++ = value;
193 temp = *++cp;
194 } else if (temp == ':') {
195 cFYI(1,("IPv6 addresses not supported for CIFS mounts yet"));
196 return -1;
197 } else
198 break;
199 }
200
201 /* check for last characters */
202 if (temp != '\0' && (!isascii(temp) || !isspace(temp)))
203 if (temp != '\\') {
204 if (temp != '/')
205 return 0;
206 else
207 (*cp = '\\'); /* switch the slash the expected way */
208 }
209 if (value > addr_class_max[end - bytes])
210 return 0;
211
212 *((__be32 *)dst) = *((__be32 *) bytes) | htonl(value);
213 return 1; /* success */
214#endif /* EXPERIMENTAL */
215} 151}
216 152
217/***************************************************************************** 153/*****************************************************************************
@@ -246,7 +182,7 @@ static const struct {
246 ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_MEDIA}, { 182 ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_MEDIA}, {
247 ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR}, 183 ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR},
248/* { This NT error code was 'sqashed' 184/* { This NT error code was 'sqashed'
249 from NT_STATUS_MORE_PROCESSING_REQUIRED to NT_STATUS_OK 185 from NT_STATUS_MORE_PROCESSING_REQUIRED to NT_STATUS_OK
250 during the session setup } */ 186 during the session setup } */
251 { 187 {
252 ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY}, { 188 ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY}, {
@@ -261,7 +197,7 @@ static const struct {
261 ERRDOS, 193, NT_STATUS_INVALID_FILE_FOR_SECTION}, { 197 ERRDOS, 193, NT_STATUS_INVALID_FILE_FOR_SECTION}, {
262 ERRDOS, ERRnoaccess, NT_STATUS_ALREADY_COMMITTED}, 198 ERRDOS, ERRnoaccess, NT_STATUS_ALREADY_COMMITTED},
263/* { This NT error code was 'sqashed' 199/* { This NT error code was 'sqashed'
264 from NT_STATUS_ACCESS_DENIED to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE 200 from NT_STATUS_ACCESS_DENIED to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE
265 during the session setup } */ 201 during the session setup } */
266 { 202 {
267 ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, { 203 ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, {
@@ -331,7 +267,7 @@ static const struct {
331 ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACCOUNT_NAME}, { 267 ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACCOUNT_NAME}, {
332 ERRHRD, ERRgeneral, NT_STATUS_USER_EXISTS}, 268 ERRHRD, ERRgeneral, NT_STATUS_USER_EXISTS},
333/* { This NT error code was 'sqashed' 269/* { This NT error code was 'sqashed'
334 from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE 270 from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE
335 during the session setup } */ 271 during the session setup } */
336 { 272 {
337 ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, { 273 ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, {
@@ -341,7 +277,7 @@ static const struct {
341 ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_GROUP}, { 277 ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_GROUP}, {
342 ERRHRD, ERRgeneral, NT_STATUS_LAST_ADMIN}, 278 ERRHRD, ERRgeneral, NT_STATUS_LAST_ADMIN},
343/* { This NT error code was 'sqashed' 279/* { This NT error code was 'sqashed'
344 from NT_STATUS_WRONG_PASSWORD to NT_STATUS_LOGON_FAILURE 280 from NT_STATUS_WRONG_PASSWORD to NT_STATUS_LOGON_FAILURE
345 during the session setup } */ 281 during the session setup } */
346 { 282 {
347 ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, { 283 ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, {
@@ -393,8 +329,8 @@ static const struct {
393 ERRHRD, ERRgeneral, NT_STATUS_FILE_INVALID}, { 329 ERRHRD, ERRgeneral, NT_STATUS_FILE_INVALID}, {
394 ERRHRD, ERRgeneral, NT_STATUS_ALLOTTED_SPACE_EXCEEDED}, 330 ERRHRD, ERRgeneral, NT_STATUS_ALLOTTED_SPACE_EXCEEDED},
395/* { This NT error code was 'sqashed' 331/* { This NT error code was 'sqashed'
396 from NT_STATUS_INSUFFICIENT_RESOURCES to NT_STATUS_INSUFF_SERVER_RESOURCES 332 from NT_STATUS_INSUFFICIENT_RESOURCES to
397 during the session setup } */ 333 NT_STATUS_INSUFF_SERVER_RESOURCES during the session setup } */
398 { 334 {
399 ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, { 335 ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, {
400 ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, { 336 ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, {
@@ -638,8 +574,8 @@ static const struct {
638 ERRDOS, 19, NT_STATUS_TOO_LATE}, { 574 ERRDOS, 19, NT_STATUS_TOO_LATE}, {
639 ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_LSA_SECRET}, 575 ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_LSA_SECRET},
640/* { This NT error code was 'sqashed' 576/* { This NT error code was 'sqashed'
641 from NT_STATUS_NO_TRUST_SAM_ACCOUNT to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE 577 from NT_STATUS_NO_TRUST_SAM_ACCOUNT to
642 during the session setup } */ 578 NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE during the session setup } */
643 { 579 {
644 ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_SAM_ACCOUNT}, { 580 ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_SAM_ACCOUNT}, {
645 ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_DOMAIN_FAILURE}, { 581 ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_DOMAIN_FAILURE}, {
@@ -658,7 +594,7 @@ static const struct {
658 ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, { 594 ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, {
659 ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT}, 595 ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT},
660/* { This NT error code was 'sqashed' 596/* { This NT error code was 'sqashed'
661 from NT_STATUS_DOMAIN_TRUST_INCONSISTENT to NT_STATUS_LOGON_FAILURE 597 from NT_STATUS_DOMAIN_TRUST_INCONSISTENT to NT_STATUS_LOGON_FAILURE
662 during the session setup } */ 598 during the session setup } */
663 { 599 {
664 ERRDOS, ERRnoaccess, NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, { 600 ERRDOS, ERRnoaccess, NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, {
@@ -789,7 +725,7 @@ cifs_print_status(__u32 status_code)
789 if (((nt_errs[idx].nt_errcode) & 0xFFFFFF) == 725 if (((nt_errs[idx].nt_errcode) & 0xFFFFFF) ==
790 (status_code & 0xFFFFFF)) { 726 (status_code & 0xFFFFFF)) {
791 printk(KERN_NOTICE "Status code returned 0x%08x %s\n", 727 printk(KERN_NOTICE "Status code returned 0x%08x %s\n",
792 status_code,nt_errs[idx].nt_errstr); 728 status_code, nt_errs[idx].nt_errstr);
793 } 729 }
794 idx++; 730 idx++;
795 } 731 }
@@ -821,7 +757,7 @@ int
821map_smb_to_linux_error(struct smb_hdr *smb) 757map_smb_to_linux_error(struct smb_hdr *smb)
822{ 758{
823 unsigned int i; 759 unsigned int i;
824 int rc = -EIO; /* if transport error smb error may not be set */ 760 int rc = -EIO; /* if transport error smb error may not be set */
825 __u8 smberrclass; 761 __u8 smberrclass;
826 __u16 smberrcode; 762 __u16 smberrcode;
827 763
@@ -832,9 +768,10 @@ map_smb_to_linux_error(struct smb_hdr *smb)
832 return 0; 768 return 0;
833 769
834 if (smb->Flags2 & SMBFLG2_ERR_STATUS) { 770 if (smb->Flags2 & SMBFLG2_ERR_STATUS) {
835 /* translate the newer STATUS codes to old style errors and then to POSIX errors */ 771 /* translate the newer STATUS codes to old style SMB errors
772 * and then to POSIX errors */
836 __u32 err = le32_to_cpu(smb->Status.CifsError); 773 __u32 err = le32_to_cpu(smb->Status.CifsError);
837 if(cifsFYI & CIFS_RC) 774 if (cifsFYI & CIFS_RC)
838 cifs_print_status(err); 775 cifs_print_status(err);
839 ntstatus_to_dos(err, &smberrclass, &smberrcode); 776 ntstatus_to_dos(err, &smberrclass, &smberrcode);
840 } else { 777 } else {
@@ -845,38 +782,42 @@ map_smb_to_linux_error(struct smb_hdr *smb)
845 /* old style errors */ 782 /* old style errors */
846 783
847 /* DOS class smb error codes - map DOS */ 784 /* DOS class smb error codes - map DOS */
848 if (smberrclass == ERRDOS) { /* one byte field no need to byte reverse */ 785 if (smberrclass == ERRDOS) { /* 1 byte field no need to byte reverse */
849 for (i = 0; 786 for (i = 0;
850 i < 787 i <
851 sizeof (mapping_table_ERRDOS) / 788 sizeof (mapping_table_ERRDOS) /
852 sizeof (struct smb_to_posix_error); i++) { 789 sizeof (struct smb_to_posix_error); i++) {
853 if (mapping_table_ERRDOS[i].smb_err == 0) 790 if (mapping_table_ERRDOS[i].smb_err == 0)
854 break; 791 break;
855 else if (mapping_table_ERRDOS[i].smb_err == smberrcode) { 792 else if (mapping_table_ERRDOS[i].smb_err ==
793 smberrcode) {
856 rc = mapping_table_ERRDOS[i].posix_code; 794 rc = mapping_table_ERRDOS[i].posix_code;
857 break; 795 break;
858 } 796 }
859 /* else try the next error mapping one to see if it will match */ 797 /* else try next error mapping one to see if match */
860 } 798 }
861 } else if (smberrclass == ERRSRV) { /* server class of error codes */ 799 } else if (smberrclass == ERRSRV) { /* server class of error codes */
862 for (i = 0; 800 for (i = 0;
863 i < 801 i <
864 sizeof (mapping_table_ERRSRV) / 802 sizeof (mapping_table_ERRSRV) /
865 sizeof (struct smb_to_posix_error); i++) { 803 sizeof (struct smb_to_posix_error); i++) {
866 if (mapping_table_ERRSRV[i].smb_err == 0) 804 if (mapping_table_ERRSRV[i].smb_err == 0)
867 break; 805 break;
868 else if (mapping_table_ERRSRV[i].smb_err == smberrcode) { 806 else if (mapping_table_ERRSRV[i].smb_err ==
807 smberrcode) {
869 rc = mapping_table_ERRSRV[i].posix_code; 808 rc = mapping_table_ERRSRV[i].posix_code;
870 break; 809 break;
871 } 810 }
872 /* else try the next error mapping one to see if it will match */ 811 /* else try next error mapping to see if match */
873 } 812 }
874 } 813 }
875 /* else ERRHRD class errors or junk - return EIO */ 814 /* else ERRHRD class errors or junk - return EIO */
876 815
877 cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!", smberrcode,rc)); 816 cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!",
817 smberrcode, rc));
878 818
879 /* generic corrective action e.g. reconnect SMB session on ERRbaduid could be added */ 819 /* generic corrective action e.g. reconnect SMB session on
820 * ERRbaduid could be added */
880 821
881 return rc; 822 return rc;
882} 823}
@@ -910,7 +851,7 @@ smbCalcSize_LE(struct smb_hdr *ptr)
910struct timespec 851struct timespec
911cifs_NTtimeToUnix(u64 ntutc) 852cifs_NTtimeToUnix(u64 ntutc)
912{ 853{
913 struct timespec ts; 854 struct timespec ts;
914 /* BB what about the timezone? BB */ 855 /* BB what about the timezone? BB */
915 856
916 /* Subtract the NTFS time offset, then convert to 1s intervals. */ 857 /* Subtract the NTFS time offset, then convert to 1s intervals. */
@@ -918,7 +859,7 @@ cifs_NTtimeToUnix(u64 ntutc)
918 859
919 t = ntutc - NTFS_TIME_OFFSET; 860 t = ntutc - NTFS_TIME_OFFSET;
920 ts.tv_nsec = do_div(t, 10000000) * 100; 861 ts.tv_nsec = do_div(t, 10000000) * 100;
921 ts.tv_sec = t; 862 ts.tv_sec = t;
922 return ts; 863 return ts;
923} 864}
924 865
@@ -946,20 +887,20 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
946 SMB_TIME * st = (SMB_TIME *)&time; 887 SMB_TIME * st = (SMB_TIME *)&time;
947 SMB_DATE * sd = (SMB_DATE *)&date; 888 SMB_DATE * sd = (SMB_DATE *)&date;
948 889
949 cFYI(1,("date %d time %d",date, time)); 890 cFYI(1, ("date %d time %d", date, time));
950 891
951 sec = 2 * st->TwoSeconds; 892 sec = 2 * st->TwoSeconds;
952 min = st->Minutes; 893 min = st->Minutes;
953 if((sec > 59) || (min > 59)) 894 if ((sec > 59) || (min > 59))
954 cERROR(1,("illegal time min %d sec %d", min, sec)); 895 cERROR(1, ("illegal time min %d sec %d", min, sec));
955 sec += (min * 60); 896 sec += (min * 60);
956 sec += 60 * 60 * st->Hours; 897 sec += 60 * 60 * st->Hours;
957 if(st->Hours > 24) 898 if (st->Hours > 24)
958 cERROR(1,("illegal hours %d",st->Hours)); 899 cERROR(1, ("illegal hours %d", st->Hours));
959 days = sd->Day; 900 days = sd->Day;
960 month = sd->Month; 901 month = sd->Month;
961 if((days > 31) || (month > 12)) 902 if ((days > 31) || (month > 12))
962 cERROR(1,("illegal date, month %d day: %d", month, days)); 903 cERROR(1, ("illegal date, month %d day: %d", month, days));
963 month -= 1; 904 month -= 1;
964 days += total_days_of_prev_months[month]; 905 days += total_days_of_prev_months[month];
965 days += 3652; /* account for difference in days between 1980 and 1970 */ 906 days += 3652; /* account for difference in days between 1980 and 1970 */
@@ -970,15 +911,15 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
970 for years/100 except for years/400, but since the maximum number for DOS 911 for years/100 except for years/400, but since the maximum number for DOS
971 year is 2**7, the last year is 1980+127, which means we need only 912 year is 2**7, the last year is 1980+127, which means we need only
972 consider 2 special case years, ie the years 2000 and 2100, and only 913 consider 2 special case years, ie the years 2000 and 2100, and only
973 adjust for the lack of leap year for the year 2100, as 2000 was a 914 adjust for the lack of leap year for the year 2100, as 2000 was a
974 leap year (divisable by 400) */ 915 leap year (divisable by 400) */
975 if(year >= 120) /* the year 2100 */ 916 if (year >= 120) /* the year 2100 */
976 days = days - 1; /* do not count leap year for the year 2100 */ 917 days = days - 1; /* do not count leap year for the year 2100 */
977 918
978 /* adjust for leap year where we are still before leap day */ 919 /* adjust for leap year where we are still before leap day */
979 if(year != 120) 920 if (year != 120)
980 days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0); 921 days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0);
981 sec += 24 * 60 * 60 * days; 922 sec += 24 * 60 * 60 * days;
982 923
983 ts.tv_sec = sec; 924 ts.tv_sec = sec;
984 925
@@ -986,4 +927,4 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time)
986 927
987 ts.tv_nsec = 0; 928 ts.tv_nsec = 0;
988 return ts; 929 return ts;
989} 930}