00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00334
00335
00336 #include "midas.h"
00337 #include "msystem.h"
00338
00339 #ifdef OS_UNIX
00340 #include <sys/mount.h>
00341 #endif
00342
00343 static INT ss_in_async_routine_flag = 0;
00344 #ifdef LOCAL_ROUTINES
00345 #include <signal.h>
00346
00347
00348
00349
00350
00351 BOOL disable_shm_write = FALSE;
00352
00353
00354 INT ss_set_async_flag(INT flag)
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 {
00375 INT old_flag;
00376
00377 old_flag = ss_in_async_routine_flag;
00378 ss_in_async_routine_flag = flag;
00379 return old_flag;
00380 }
00381
00382
00383 INT ss_shm_open(char *name, INT size, void **adr, HNDLE * handle)
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 {
00408 INT status;
00409 char mem_name[256], file_name[256], path[256];
00410
00411
00412 sprintf(mem_name, "SM_%s", name);
00413
00414
00415 cm_get_path(path);
00416 if (path[0] == 0) {
00417 getcwd(path, 256);
00418 #if defined(OS_VMS)
00419 #elif defined(OS_UNIX)
00420 strcat(path, "/");
00421 #elif defined(OS_WINNT)
00422 strcat(path, "\\");
00423 #endif
00424 }
00425
00426 strcpy(file_name, path);
00427 #if defined (OS_UNIX)
00428 strcat(file_name, ".");
00429 #endif
00430 strcat(file_name, name);
00431 strcat(file_name, ".SHM");
00432
00433 #ifdef OS_WINNT
00434
00435 status = SS_SUCCESS;
00436
00437 {
00438 HANDLE hFile, hMap;
00439 char str[256], *p;
00440 DWORD file_size;
00441
00442
00443
00444
00445
00446 strcpy(str, path);
00447
00448
00449 while (strpbrk(str, "\\: "))
00450 *strpbrk(str, "\\: ") = '*';
00451 strcat(str, mem_name);
00452
00453
00454 p = str;
00455 while (*p)
00456 *p++ = (char) toupper(*p);
00457
00458 hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, str);
00459 if (hMap == 0) {
00460 hFile = CreateFile(file_name, GENERIC_READ | GENERIC_WRITE,
00461 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
00462 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
00463 if (!hFile) {
00464 cm_msg(MERROR, "ss_shm_open", "CreateFile() failed");
00465 return SS_FILE_ERROR;
00466 }
00467
00468 file_size = GetFileSize(hFile, NULL);
00469 if (file_size != 0xFFFFFFFF && file_size > 0)
00470 size = file_size;
00471
00472 hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, size, str);
00473
00474 if (!hMap) {
00475 status = GetLastError();
00476 cm_msg(MERROR, "ss_shm_open", "CreateFileMapping() failed, error %d", status);
00477 return SS_FILE_ERROR;
00478 }
00479
00480 CloseHandle(hFile);
00481 status = SS_CREATED;
00482 }
00483
00484 *adr = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
00485 *handle = (HNDLE) hMap;
00486
00487 if (adr == NULL) {
00488 cm_msg(MERROR, "ss_shm_open", "MapViewOfFile() failed");
00489 return SS_NO_MEMORY;
00490 }
00491
00492 return status;
00493 }
00494
00495 #endif
00496 #ifdef OS_VMS
00497
00498 status = SS_SUCCESS;
00499
00500 {
00501 int addr[2];
00502 $DESCRIPTOR(memname_dsc, "dummy");
00503 $DESCRIPTOR(filename_dsc, "dummy");
00504 memname_dsc.dsc$w_length = strlen(mem_name);
00505 memname_dsc.dsc$a_pointer = mem_name;
00506 filename_dsc.dsc$w_length = strlen(file_name);
00507 filename_dsc.dsc$a_pointer = file_name;
00508
00509 addr[0] = size;
00510 addr[1] = 0;
00511
00512 status = ppl$create_shared_memory(&memname_dsc, addr, &PPL$M_NOUNI, &filename_dsc);
00513
00514 if (status == PPL$_CREATED)
00515 status = SS_CREATED;
00516 else if (status != PPL$_NORMAL)
00517 status = SS_FILE_ERROR;
00518
00519 *adr = (void *) addr[1];
00520 *handle = 0;
00521
00522 if (adr == NULL)
00523 return SS_NO_MEMORY;
00524
00525 return status;
00526 }
00527
00528 #endif
00529 #ifdef OS_UNIX
00530
00531 status = SS_SUCCESS;
00532
00533 {
00534 int key, shmid, fh, file_size;
00535 struct shmid_ds buf;
00536
00537
00538 key = ftok(file_name, 'M');
00539
00540
00541 if (key == -1) {
00542 fh = open(file_name, O_CREAT | O_TRUNC | O_BINARY, 0644);
00543 close(fh);
00544 key = ftok(file_name, 'M');
00545
00546 if (key == -1) {
00547 cm_msg(MERROR, "ss_shm_open", "ftok() failed");
00548 return SS_FILE_ERROR;
00549 }
00550
00551 status = SS_CREATED;
00552
00553
00554
00555 shmid = shmget(key, 0, 0);
00556 shmctl(shmid, IPC_RMID, &buf);
00557 } else {
00558
00559 file_size = (INT) ss_file_size(file_name);
00560 if (file_size > 0) {
00561 if (file_size < size) {
00562 cm_msg(MERROR, "ss_shm_open", "Shared memory segment \'%s\' size %d is smaller than requested size %d. Please remove it and try again",file_name,file_size,size);
00563 return SS_NO_MEMORY;
00564 }
00565
00566 size = file_size;
00567 }
00568 }
00569
00570
00571 shmid = shmget(key, size, 0);
00572 if (shmid == -1) {
00573
00574 shmid = shmget(key, size, IPC_CREAT|IPC_EXCL);
00575 if (shmid == -1 && errno == EEXIST)
00576 {
00577 cm_msg(MERROR, "ss_shm_open", "Shared memory segment with key 0x%x already exists, please remove it manually: ipcrm -M 0x%x",key,key);
00578 return SS_NO_MEMORY;
00579 }
00580 status = SS_CREATED;
00581 }
00582
00583 if (shmid == -1) {
00584 cm_msg(MERROR, "ss_shm_open", "shmget(key=0x%x,size=%d) failed, errno %d (%s)", key, size, errno, strerror(errno));
00585 return SS_NO_MEMORY;
00586 }
00587
00588 buf.shm_perm.uid = getuid();
00589 buf.shm_perm.gid = getgid();
00590 buf.shm_perm.mode = 0666;
00591 shmctl(shmid, IPC_SET, &buf);
00592
00593 *adr = shmat(shmid, 0, 0);
00594 *handle = (HNDLE) shmid;
00595
00596 if ((*adr) == (void *) (-1)) {
00597 cm_msg(MERROR, "ss_shm_open","shmat(shmid=%d) failed, errno %d (%s)", shmid, errno, strerror(errno));
00598 return SS_NO_MEMORY;
00599 }
00600
00601
00602 if (status == SS_CREATED) {
00603 fh = open(file_name, O_RDONLY, 0644);
00604 if (fh == -1)
00605 fh = open(file_name, O_CREAT | O_RDWR, 0644);
00606 else
00607 read(fh, *adr, size);
00608 close(fh);
00609 }
00610
00611 return status;
00612 }
00613
00614 #endif
00615 }
00616
00617
00618 INT ss_shm_close(char *name, void *adr, HNDLE handle, INT destroy_flag)
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642 {
00643 char mem_name[256], file_name[256], path[256];
00644
00645
00646
00647
00648
00649 sprintf(mem_name, "SM_%s", name);
00650
00651
00652 cm_get_path(path);
00653 if (path[0] == 0) {
00654 getcwd(path, 256);
00655 #if defined(OS_VMS)
00656 #elif defined(OS_UNIX)
00657 strcat(path, "/");
00658 #elif defined(OS_WINNT)
00659 strcat(path, "\\");
00660 #endif
00661 }
00662
00663 strcpy(file_name, path);
00664 #if defined (OS_UNIX)
00665 strcat(file_name, ".");
00666 #endif
00667 strcat(file_name, name);
00668 strcat(file_name, ".SHM");
00669
00670 #ifdef OS_WINNT
00671
00672 if (!UnmapViewOfFile(adr))
00673 return SS_INVALID_ADDRESS;
00674
00675 CloseHandle((HANDLE) handle);
00676
00677 return SS_SUCCESS;
00678
00679 #endif
00680 #ifdef OS_VMS
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704 return SS_INVALID_ADDRESS;
00705
00706 #endif
00707 #ifdef OS_UNIX
00708
00709 {
00710 struct shmid_ds buf;
00711 FILE *fh;
00712
00713
00714 if (shmctl(handle, IPC_STAT, &buf) < 0) {
00715 cm_msg(MERROR, "ss_shm_close", "shmctl(shmid=%d,IPC_STAT) failed, errno %d (%s)",handle,errno,strerror(errno));
00716 return SS_INVALID_HANDLE;
00717 }
00718
00719
00720 if (buf.shm_nattch == 1) {
00721 if (!disable_shm_write) {
00722 fh = fopen(file_name, "w");
00723
00724 if (fh == NULL) {
00725 cm_msg(MERROR, "ss_shm_close",
00726 "Cannot write to file %s, please check protection", file_name);
00727 } else {
00728
00729 fwrite(adr, 1, buf.shm_segsz, fh);
00730 fclose(fh);
00731 }
00732 }
00733
00734 if (shmdt(adr) < 0) {
00735 cm_msg(MERROR, "ss_shm_close", "shmdt(shmid=%d) failed, errno %d (%s)",handle,errno,strerror(errno));
00736 return SS_INVALID_ADDRESS;
00737 }
00738
00739 if (shmctl(handle, IPC_RMID, &buf) < 0) {
00740 cm_msg(MERROR, "ss_shm_close", "shmctl(shmid=%d,IPC_RMID) failed, errno %d (%s)",handle,errno,strerror(errno));
00741 return SS_INVALID_ADDRESS;
00742 }
00743 } else
00744
00745 if (shmdt(adr) < 0) {
00746 cm_msg(MERROR, "ss_shm_close", "shmdt(shmid=%d) failed, errno %d (%s)",handle,errno,strerror(errno));
00747 return SS_INVALID_ADDRESS;
00748 }
00749
00750 return SS_SUCCESS;
00751 }
00752
00753 #endif
00754 }
00755
00756
00757 INT ss_shm_protect(HNDLE handle, void *adr)
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777 {
00778 #ifdef OS_WINNT
00779
00780 if (!UnmapViewOfFile(adr))
00781 return SS_INVALID_ADDRESS;
00782
00783 #endif
00784 #ifdef OS_UNIX
00785
00786 if (shmdt(adr) < 0) {
00787 cm_msg(MERROR, "ss_shm_protect", "shmdt() failed");
00788 return SS_INVALID_ADDRESS;
00789 }
00790 #endif
00791 return SS_SUCCESS;
00792 }
00793
00794
00795 INT ss_shm_unprotect(HNDLE handle, void **adr)
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815 {
00816 #ifdef OS_WINNT
00817
00818 *adr = MapViewOfFile((HANDLE) handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
00819
00820 if (*adr == NULL) {
00821 cm_msg(MERROR, "ss_shm_unprotect", "MapViewOfFile() failed");
00822 return SS_NO_MEMORY;
00823 }
00824 #endif
00825 #ifdef OS_UNIX
00826
00827 *adr = shmat(handle, 0, 0);
00828
00829 if ((*adr) == (void *) (-1)) {
00830 cm_msg(MERROR, "ss_shm_unprotect", "shmat() failed, errno = %d", errno);
00831 return SS_NO_MEMORY;
00832 }
00833 #endif
00834
00835 return SS_SUCCESS;
00836 }
00837
00838
00839 INT ss_shm_flush(char *name, void *adr, INT size)
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859 {
00860 char mem_name[256], file_name[256], path[256];
00861
00862
00863
00864
00865
00866 sprintf(mem_name, "SM_%s", name);
00867
00868
00869 cm_get_path(path);
00870 if (path[0] == 0) {
00871 getcwd(path, 256);
00872 #if defined(OS_VMS)
00873 #elif defined(OS_UNIX)
00874 strcat(path, "/");
00875 #elif defined(OS_WINNT)
00876 strcat(path, "\\");
00877 #endif
00878 }
00879
00880 strcpy(file_name, path);
00881 #if defined (OS_UNIX)
00882 strcat(file_name, ".");
00883 #endif
00884 strcat(file_name, name);
00885 strcat(file_name, ".SHM");
00886
00887 #ifdef OS_WINNT
00888
00889 if (!FlushViewOfFile(adr, size))
00890 return SS_INVALID_ADDRESS;
00891
00892 return SS_SUCCESS;
00893
00894 #endif
00895 #ifdef OS_VMS
00896
00897 return SS_SUCCESS;
00898
00899 #endif
00900 #ifdef OS_UNIX
00901
00902 if (!disable_shm_write) {
00903 FILE *fh;
00904
00905 fh = fopen(file_name, "w");
00906
00907 if (fh == NULL) {
00908 cm_msg(MERROR, "ss_shm_flush",
00909 "Cannot write to file %s, please check protection", file_name);
00910 } else {
00911
00912 fwrite(adr, 1, size, fh);
00913 fclose(fh);
00914 }
00915 }
00916 return SS_SUCCESS;
00917
00918 #endif
00919 }
00920
00921
00922 INT ss_getthandle(void)
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939 {
00940 #ifdef OS_WINNT
00941 HANDLE hThread;
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
00953 GetCurrentProcess(), &hThread, THREAD_ALL_ACCESS, TRUE, 0);
00954
00955 return (INT)hThread;
00956
00957 #endif
00958 #ifdef OS_VMS
00959
00960 return 0;
00961
00962 #endif
00963 #ifdef OS_UNIX
00964
00965 return ss_getpid();
00966
00967 #endif
00968 }
00969
00970 #endif
00971
00972
00973 struct {
00974 char c;
00975 double d;
00976 } test_align;
00977
00978 INT ss_get_struct_align()
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000 {
01001 return (PTYPE) (&test_align.d) - (PTYPE) & test_align.c;
01002 }
01003
01004
01005 INT ss_getpid(void)
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022 {
01023 #ifdef OS_WINNT
01024
01025 return (int) GetCurrentProcessId();
01026
01027 #endif
01028 #ifdef OS_VMS
01029
01030 return getpid();
01031
01032 #endif
01033 #ifdef OS_UNIX
01034
01035 return getpid();
01036
01037 #endif
01038 #ifdef OS_VXWORKS
01039
01040 return 0;
01041
01042 #endif
01043 #ifdef OS_MSDOS
01044
01045 return 0;
01046
01047 #endif
01048 }
01049
01050
01051
01052 static BOOL _single_thread = FALSE;
01053
01054 void ss_force_single_thread()
01055 {
01056 _single_thread = TRUE;
01057 }
01058
01059 INT ss_gettid(void)
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076 {
01077
01078 if (_single_thread)
01079 return 1;
01080
01081 #ifdef OS_MSDOS
01082
01083 return 0;
01084
01085 #endif
01086 #ifdef OS_WINNT
01087
01088 return (int) GetCurrentThreadId();
01089
01090 #endif
01091 #ifdef OS_VMS
01092
01093 return ss_getpid();
01094
01095 #endif
01096 #ifdef OS_UNIX
01097
01098 return ss_getpid();
01099
01100 #endif
01101 #ifdef OS_VXWORKS
01102
01103 return ss_getpid();
01104
01105 #endif
01106 }
01107
01108
01109
01110 #ifdef OS_UNIX
01111 void catch_sigchld(int signo)
01112 {
01113 int status;
01114
01115 wait(&status);
01116 return;
01117 }
01118 #endif
01119
01120 INT ss_spawnv(INT mode, char *cmdname, char *argv[])
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143 {
01144 #ifdef OS_WINNT
01145
01146 if (spawnvp(mode, cmdname, argv) < 0)
01147 return SS_INVALID_NAME;
01148
01149 return SS_SUCCESS;
01150
01151 #endif
01152
01153 #ifdef OS_MSDOS
01154
01155 spawnvp((int) mode, cmdname, argv);
01156
01157 return SS_SUCCESS;
01158
01159 #endif
01160
01161 #ifdef OS_VMS
01162
01163 {
01164 char cmdstring[500], *pc;
01165 INT i, flags, status;
01166 va_list argptr;
01167
01168 $DESCRIPTOR(cmdstring_dsc, "dummy");
01169
01170 if (mode & P_DETACH) {
01171 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
01172 cmdstring_dsc.dsc$a_pointer = cmdstring;
01173
01174 status = sys$creprc(0, &cmdstring_dsc,
01175 0, 0, 0, 0, 0, NULL, 4, 0, 0, PRC$M_DETACH);
01176 } else {
01177 flags = (mode & P_NOWAIT) ? 1 : 0;
01178
01179 for (pc = argv[0] + strlen(argv[0]); *pc != ']' && pc != argv[0]; pc--);
01180 if (*pc == ']')
01181 pc++;
01182
01183 strcpy(cmdstring, pc);
01184
01185 if (strchr(cmdstring, ';'))
01186 *strchr(cmdstring, ';') = 0;
01187
01188 strcat(cmdstring, " ");
01189
01190 for (i = 1; argv[i] != NULL; i++) {
01191 strcat(cmdstring, argv[i]);
01192 strcat(cmdstring, " ");
01193 }
01194
01195 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
01196 cmdstring_dsc.dsc$a_pointer = cmdstring;
01197
01198 status = lib$spawn(&cmdstring_dsc, 0, 0, &flags, NULL, 0, 0, 0, 0, 0, 0, 0, 0);
01199 }
01200
01201 return BM_SUCCESS;
01202 }
01203
01204 #endif
01205 #ifdef OS_UNIX
01206 pid_t child_pid;
01207
01208 #ifdef OS_ULTRIX
01209 union wait *status;
01210 #else
01211 int status;
01212 #endif
01213
01214 if ((child_pid = fork()) < 0)
01215 return (-1);
01216
01217 if (child_pid == 0) {
01218
01219 child_pid = execvp(cmdname, argv);
01220 return SS_SUCCESS;
01221 } else {
01222
01223 if (mode == P_WAIT)
01224 #ifdef OS_ULTRIX
01225 waitpid(child_pid, status, WNOHANG);
01226 #else
01227 waitpid(child_pid, &status, WNOHANG);
01228 #endif
01229
01230 else
01231
01232 signal(SIGCHLD, catch_sigchld);
01233 }
01234
01235 return SS_SUCCESS;
01236
01237 #endif
01238 }
01239
01240
01241 INT ss_shell(int sock)
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258 {
01259 #ifdef OS_WINNT
01260
01261 HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
01262 hChildStdoutRd, hChildStdoutWr,
01263 hChildStderrRd, hChildStderrWr, hSaveStdin, hSaveStdout, hSaveStderr;
01264
01265 SECURITY_ATTRIBUTES saAttr;
01266 PROCESS_INFORMATION piProcInfo;
01267 STARTUPINFO siStartInfo;
01268 char buffer[256], cmd[256];
01269 DWORD dwRead, dwWritten, dwAvail, i, i_cmd;
01270 fd_set readfds;
01271 struct timeval timeout;
01272
01273
01274 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
01275 saAttr.bInheritHandle = TRUE;
01276 saAttr.lpSecurityDescriptor = NULL;
01277
01278
01279 hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
01280
01281
01282 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
01283 return 0;
01284
01285
01286 if (!SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
01287 return 0;
01288
01289
01290
01291 hSaveStderr = GetStdHandle(STD_ERROR_HANDLE);
01292
01293
01294 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
01295 return 0;
01296
01297
01298 if (!SetStdHandle(STD_ERROR_HANDLE, hChildStderrWr))
01299 return 0;
01300
01301
01302
01303 hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
01304
01305
01306 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
01307 return 0;
01308
01309
01310 if (!SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
01311 return 0;
01312
01313
01314 if (!DuplicateHandle(GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), &hChildStdinWrDup, 0, FALSE,
01315 DUPLICATE_SAME_ACCESS))
01316 return 0;
01317
01318 CloseHandle(hChildStdinWr);
01319
01320
01321 memset(&siStartInfo, 0, sizeof(siStartInfo));
01322 siStartInfo.cb = sizeof(STARTUPINFO);
01323 siStartInfo.lpReserved = NULL;
01324 siStartInfo.lpReserved2 = NULL;
01325 siStartInfo.cbReserved2 = 0;
01326 siStartInfo.lpDesktop = NULL;
01327 siStartInfo.dwFlags = 0;
01328
01329 if (!CreateProcess(NULL, "cmd /Q",
01330 NULL,
01331 NULL,
01332 TRUE,
01333 0,
01334 NULL,
01335 NULL,
01336 &siStartInfo,
01337 &piProcInfo))
01338 return 0;
01339
01340
01341 SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
01342 SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
01343 SetStdHandle(STD_ERROR_HANDLE, hSaveStderr);
01344
01345 i_cmd = 0;
01346
01347 do {
01348
01349 do {
01350 if (!PeekNamedPipe(hChildStderrRd, buffer, 256, &dwRead, &dwAvail, NULL))
01351 break;
01352
01353 if (dwRead > 0) {
01354 ReadFile(hChildStderrRd, buffer, 256, &dwRead, NULL);
01355 send(sock, buffer, dwRead, 0);
01356 }
01357 } while (dwAvail > 0);
01358
01359
01360 do {
01361 if (!PeekNamedPipe(hChildStdoutRd, buffer, 256, &dwRead, &dwAvail, NULL))
01362 break;
01363 if (dwRead > 0) {
01364 ReadFile(hChildStdoutRd, buffer, 256, &dwRead, NULL);
01365 send(sock, buffer, dwRead, 0);
01366 }
01367 } while (dwAvail > 0);
01368
01369
01370
01371 if (!GetExitCodeProcess(piProcInfo.hProcess, &i))
01372 break;
01373 if (i != STILL_ACTIVE)
01374 break;
01375
01376
01377 FD_ZERO(&readfds);
01378 FD_SET(sock, &readfds);
01379 timeout.tv_sec = 0;
01380 timeout.tv_usec = 100;
01381 select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
01382
01383 if (FD_ISSET(sock, &readfds)) {
01384 i = recv(sock, cmd + i_cmd, 1, 0);
01385 if (i <= 0)
01386 break;
01387
01388
01389 if (cmd[i_cmd] == 8) {
01390 if (i_cmd > 0) {
01391 send(sock, "\b \b", 3, 0);
01392 i_cmd -= 1;
01393 }
01394 } else if (cmd[i_cmd] >= ' ' || cmd[i_cmd] == 13 || cmd[i_cmd] == 10) {
01395 send(sock, cmd + i_cmd, 1, 0);
01396 i_cmd += i;
01397 }
01398 }
01399
01400
01401 if (cmd[i_cmd - 1] == 10) {
01402 WriteFile(hChildStdinWrDup, cmd, i_cmd, &dwWritten, NULL);
01403 i_cmd = 0;
01404 }
01405
01406 } while (TRUE);
01407
01408 CloseHandle(hChildStdinWrDup);
01409 CloseHandle(hChildStdinRd);
01410 CloseHandle(hChildStderrRd);
01411 CloseHandle(hChildStdoutRd);
01412
01413 return SS_SUCCESS;
01414
01415 #endif
01416
01417 #ifdef OS_UNIX
01418 #ifndef NO_PTY
01419 pid_t pid;
01420 int i, pipe;
01421 char line[32], buffer[1024], shell[32];
01422 fd_set readfds;
01423
01424 if ((pid = forkpty(&pipe, line, NULL, NULL)) < 0)
01425 return 0;
01426 else if (pid > 0) {
01427
01428
01429 do {
01430 FD_ZERO(&readfds);
01431 FD_SET(sock, &readfds);
01432 FD_SET(pipe, &readfds);
01433
01434 select(FD_SETSIZE, (void *) &readfds, NULL, NULL, NULL);
01435
01436 if (FD_ISSET(sock, &readfds)) {
01437 memset(buffer, 0, sizeof(buffer));
01438 i = recv(sock, buffer, sizeof(buffer), 0);
01439 if (i <= 0)
01440 break;
01441 if (write(pipe, buffer, i) != i)
01442 break;
01443 }
01444
01445 if (FD_ISSET(pipe, &readfds)) {
01446 memset(buffer, 0, sizeof(buffer));
01447 i = read(pipe, buffer, sizeof(buffer));
01448 if (i <= 0)
01449 break;
01450 send(sock, buffer, i, 0);
01451 }
01452
01453 } while (1);
01454 } else {
01455
01456
01457 if (getenv("SHELL"))
01458 strlcpy(shell, getenv("SHELL"), sizeof(shell));
01459 else
01460 strcpy(shell, "/bin/sh");
01461 execl(shell, shell, 0);
01462 }
01463 #else
01464 send(sock, "not implemented\n", 17, 0);
01465 #endif
01466
01467 return SS_SUCCESS;
01468
01469 #endif
01470 }
01471
01472
01473 static BOOL _daemon_flag;
01474
01475 INT ss_daemon_init(BOOL keep_stdout)
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493 {
01494 #ifdef OS_UNIX
01495
01496
01497 int i, fd, pid;
01498
01499 if ((pid = fork()) < 0)
01500 return SS_ABORT;
01501 else if (pid != 0)
01502 exit(0);
01503
01504
01505
01506 _daemon_flag = TRUE;
01507
01508
01509
01510 for (i = 0; i < 3; i++) {
01511 if (keep_stdout && ((i == 1) || (i == 2)))
01512 continue;
01513
01514 close(i);
01515 fd = open("/dev/null", O_RDWR, 0);
01516 if (fd < 0)
01517 fd = open("/dev/null", O_WRONLY, 0);
01518 if (fd < 0) {
01519 cm_msg(MERROR, "ss_system", "Can't open /dev/null");
01520 return SS_ABORT;
01521 }
01522 if (fd != i) {
01523 cm_msg(MERROR, "ss_system", "Did not get file descriptor");
01524 return SS_ABORT;
01525 }
01526 }
01527
01528 setsid();
01529 umask(0);
01530
01531 #endif
01532
01533 return SS_SUCCESS;
01534 }
01535
01536
01537 BOOL ss_existpid(INT pid)
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555 {
01556 #ifdef OS_UNIX
01557
01558 return (kill(pid, 0) == 0 ? TRUE : FALSE);
01559 #else
01560 cm_msg(MINFO, "ss_existpid", "implemented for UNIX only");
01561 return FALSE;
01562 #endif
01563 }
01564
01565
01566
01567 #endif
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587 INT ss_system(char *command)
01588 {
01589 #ifdef OS_UNIX
01590 INT childpid;
01591
01592 return ss_exec(command, &childpid);
01593
01594 #else
01595
01596 system(command);
01597 return SS_SUCCESS;
01598
01599 #endif
01600 }
01601
01602
01603 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01604
01605
01606 INT ss_exec(char *command, INT * pid)
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625 {
01626 #ifdef OS_UNIX
01627
01628
01629 int i, fd;
01630
01631 if ((*pid = fork()) < 0)
01632 return SS_ABORT;
01633 else if (*pid != 0) {
01634
01635 signal(SIGCHLD, catch_sigchld);
01636 return SS_SUCCESS;
01637 }
01638
01639
01640
01641
01642 for (i = 0; i < 256; i++)
01643 close(i);
01644
01645
01646
01647 for (i = 0; i < 3; i++) {
01648 fd = open("/dev/null", O_RDWR, 0);
01649 if (fd < 0)
01650 fd = open("/dev/null", O_WRONLY, 0);
01651 if (fd < 0) {
01652 cm_msg(MERROR, "ss_exec", "Can't open /dev/null");
01653 return SS_ABORT;
01654 }
01655 if (fd != i) {
01656 cm_msg(MERROR, "ss_exec", "Did not get file descriptor");
01657 return SS_ABORT;
01658 }
01659 }
01660
01661 setsid();
01662
01663 umask(0);
01664
01665
01666 execl("/bin/sh", "sh", "-c", command, NULL);
01667
01668 #else
01669
01670 system(command);
01671
01672 #endif
01673
01674 return SS_SUCCESS;
01675 }
01676
01677
01678 #endif
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710
01711
01712
01713 midas_thread_t ss_thread_create(INT(*thread_func) (void *), void *param)
01714 {
01715 #if defined(OS_WINNT)
01716
01717 HANDLE status;
01718 DWORD thread_id;
01719
01720 if (thread_func == NULL) {
01721 return 0;
01722 }
01723
01724 status = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) thread_func,
01725 (LPVOID) param, 0, &thread_id);
01726
01727 return status == NULL ? 0 : (midas_thread_t)thread_id;
01728
01729 #elif defined(OS_MSDOS)
01730
01731 return 0;
01732
01733 #elif defined(OS_VMS)
01734
01735 return 0;
01736
01737 #elif defined(OS_VXWORKS)
01738
01739
01740
01741
01742
01743
01744
01745
01746 INT status;
01747 VX_TASK_SPAWN *ts;
01748
01749 ts = (VX_TASK_SPAWN *) param;
01750 status =
01751 taskSpawn(ts->name, ts->priority, ts->options, ts->stackSize,
01752 (FUNCPTR) thread_func, ts->arg1, ts->arg2, ts->arg3,
01753 ts->arg4, ts->arg5, ts->arg6, ts->arg7, ts->arg8, ts->arg9, ts->arg10);
01754
01755 return status == ERROR ? 0 : status;
01756
01757 #elif defined(OS_UNIX)
01758
01759 INT status;
01760 pthread_t thread_id;
01761
01762 status = pthread_create(&thread_id, NULL, (void *) thread_func, param);
01763
01764 return status != 0 ? 0 : thread_id;
01765
01766 #endif
01767 }
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787 INT ss_thread_kill(midas_thread_t thread_id)
01788 {
01789 #if defined(OS_WINNT)
01790
01791 DWORD status;
01792
01793 status = TerminateThread(thread_id, 0);
01794
01795 return status != 0 ? SS_SUCCESS : SS_NO_THREAD;
01796
01797 #elif defined(OS_MSDOS)
01798
01799 return 0;
01800
01801 #elif defined(OS_VMS)
01802
01803 return 0;
01804
01805 #elif defined(OS_VXWORKS)
01806
01807 INT status;
01808 status = taskDelete(thread_id);
01809 return status == OK ? 0 : ERROR;
01810
01811 #elif defined(OS_UNIX)
01812
01813 INT status;
01814 status = pthread_kill(thread_id, SIGKILL);
01815 return status == 0 ? SS_SUCCESS : SS_NO_THREAD;
01816
01817 #endif
01818 }
01819
01820
01821 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01822
01823
01824 static INT skip_mutex_handle = -1;
01825
01826 INT ss_mutex_create(char *name, HNDLE * mutex_handle)
01827
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853 {
01854 char mutex_name[256], path[256], file_name[256];
01855
01856
01857 sprintf(mutex_name, "MX_%s", name);
01858
01859 #ifdef OS_VXWORKS
01860
01861
01862
01863 if ((*((SEM_ID *) mutex_handle) = semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL)
01864 return SS_NO_MUTEX;
01865 return SS_CREATED;
01866
01867 #endif
01868
01869
01870 cm_get_path(path);
01871 if (path[0] == 0) {
01872 getcwd(path, 256);
01873 #if defined(OS_VMS)
01874 #elif defined(OS_UNIX)
01875 strcat(path, "/");
01876 #elif defined(OS_WINNT)
01877 strcat(path, "\\");
01878 #endif
01879 }
01880
01881 strcpy(file_name, path);
01882 #if defined (OS_UNIX)
01883 strcat(file_name, ".");
01884 #endif
01885 strcat(file_name, name);
01886 strcat(file_name, ".SHM");
01887
01888 #ifdef OS_WINNT
01889
01890 *mutex_handle = (HNDLE) CreateMutex(NULL, FALSE, mutex_name);
01891
01892 if (*mutex_handle == 0)
01893 return SS_NO_MUTEX;
01894
01895 return SS_CREATED;
01896
01897 #endif
01898 #ifdef OS_VMS
01899
01900
01901
01902 {
01903 INT status;
01904 $DESCRIPTOR(mutexname_dsc, "dummy");
01905 mutexname_dsc.dsc$w_length = strlen(mutex_name);
01906 mutexname_dsc.dsc$a_pointer = mutex_name;
01907
01908 *mutex_handle = (HNDLE) malloc(8);
01909
01910 status = sys$enqw(0, LCK$K_NLMODE, *mutex_handle, 0, &mutexname_dsc,
01911 0, 0, 0, 0, 0, 0);
01912
01913 if (status != SS$_NORMAL) {
01914 free((void *) *mutex_handle);
01915 *mutex_handle = 0;
01916 }
01917
01918 if (*mutex_handle == 0)
01919 return SS_NO_MUTEX;
01920
01921 return SS_CREATED;
01922 }
01923
01924 #endif
01925 #ifdef OS_UNIX
01926
01927 {
01928 INT key, status, fh;
01929 struct semid_ds buf;
01930
01931 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(OS_FREEBSD)
01932 union semun arg;
01933 #else
01934 union semun {
01935 INT val;
01936 struct semid_ds *buf;
01937 ushort *array;
01938 } arg;
01939 #endif
01940
01941 status = SS_SUCCESS;
01942
01943
01944 key = ftok(file_name, 'M');
01945 if (key < 0) {
01946 fh = open(file_name, O_CREAT, 0644);
01947 close(fh);
01948 key = ftok(file_name, 'M');
01949 status = SS_CREATED;
01950 }
01951
01952
01953 *mutex_handle = (HNDLE) semget(key, 1, 0);
01954 if (*mutex_handle < 0) {
01955 *mutex_handle = (HNDLE) semget(key, 1, IPC_CREAT);
01956 status = SS_CREATED;
01957 }
01958
01959 if (*mutex_handle < 0) {
01960 cm_msg(MERROR, "ss_mutex_mutex", "semget() failed, errno = %d", errno);
01961 return SS_NO_MUTEX;
01962 }
01963
01964 buf.sem_perm.uid = getuid();
01965 buf.sem_perm.gid = getgid();
01966 buf.sem_perm.mode = 0666;
01967 arg.buf = &buf;
01968
01969 semctl(*mutex_handle, 0, IPC_SET, arg);
01970
01971
01972 if (status == SS_CREATED) {
01973 arg.val = 1;
01974 if (semctl(*mutex_handle, 0, SETVAL, arg) < 0)
01975 return SS_NO_MUTEX;
01976 }
01977
01978 return SS_SUCCESS;
01979 }
01980 #endif
01981
01982 #ifdef OS_MSDOS
01983 return SS_NO_MUTEX;
01984 #endif
01985 }
01986
01987
01988 INT ss_mutex_wait_for(HNDLE mutex_handle, INT timeout)
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008 {
02009 INT status;
02010
02011 #ifdef OS_WINNT
02012
02013 status = WaitForSingleObject((HANDLE) mutex_handle, timeout == 0 ? INFINITE : timeout);
02014 if (status == WAIT_FAILED)
02015 return SS_NO_MUTEX;
02016 if (status == WAIT_TIMEOUT)
02017 return SS_TIMEOUT;
02018
02019 return SS_SUCCESS;
02020 #endif
02021 #ifdef OS_VMS
02022 status = sys$enqw(0, LCK$K_EXMODE, mutex_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
02023 if (status != SS$_NORMAL)
02024 return SS_NO_MUTEX;
02025 return SS_SUCCESS;
02026
02027 #endif
02028 #ifdef OS_VXWORKS
02029
02030 status = semTake((SEM_ID) mutex_handle, timeout == 0 ? WAIT_FOREVER : timeout >> 4);
02031 if (status == ERROR)
02032 return SS_NO_MUTEX;
02033 return SS_SUCCESS;
02034
02035 #endif
02036 #ifdef OS_UNIX
02037 {
02038 DWORD start_time;
02039 struct sembuf sb;
02040
02041 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(OS_FREEBSD)
02042 union semun arg;
02043 #else
02044 union semun {
02045 INT val;
02046 struct semid_ds *buf;
02047 ushort *array;
02048 } arg;
02049 #endif
02050
02051 sb.sem_num = 0;
02052 sb.sem_op = -1;
02053 sb.sem_flg = SEM_UNDO;
02054
02055 memset(&arg, 0, sizeof(arg));
02056
02057
02058
02059 if (ss_in_async_routine_flag)
02060 if (semctl(mutex_handle, 0, GETPID, arg) == getpid())
02061 if (semctl(mutex_handle, 0, GETVAL, arg) == 0) {
02062 skip_mutex_handle = mutex_handle;
02063 return SS_SUCCESS;
02064 }
02065
02066 skip_mutex_handle = -1;
02067
02068 start_time = ss_millitime();
02069
02070 do {
02071 status = semop(mutex_handle, &sb, 1);
02072
02073
02074 if (status == 0)
02075 break;
02076
02077
02078 if (errno == EINTR) {
02079
02080 if (timeout > 0 && ss_millitime() - start_time > timeout)
02081 return SS_TIMEOUT;
02082
02083 continue;
02084 }
02085
02086 return SS_NO_MUTEX;
02087 } while (1);
02088
02089 return SS_SUCCESS;
02090 }
02091 #endif
02092
02093 #ifdef OS_MSDOS
02094 return SS_NO_MUTEX;
02095 #endif
02096 }
02097
02098
02099 INT ss_mutex_release(HNDLE mutex_handle)
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117 {
02118 INT status;
02119
02120 #ifdef OS_WINNT
02121
02122 status = ReleaseMutex((HANDLE) mutex_handle);
02123
02124 if (status == FALSE)
02125 return SS_NO_MUTEX;
02126
02127 return SS_SUCCESS;
02128
02129 #endif
02130 #ifdef OS_VMS
02131
02132 status = sys$enqw(0, LCK$K_NLMODE, mutex_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0, 0, 0);
02133
02134 if (status != SS$_NORMAL)
02135 return SS_NO_MUTEX;
02136
02137 return SS_SUCCESS;
02138
02139 #endif
02140
02141 #ifdef OS_VXWORKS
02142
02143 if (semGive((SEM_ID) mutex_handle) == ERROR)
02144 return SS_NO_MUTEX;
02145 return SS_SUCCESS;
02146 #endif
02147
02148 #ifdef OS_UNIX
02149 {
02150 struct sembuf sb;
02151
02152 sb.sem_num = 0;
02153 sb.sem_op = 1;
02154 sb.sem_flg = SEM_UNDO;
02155
02156 if (mutex_handle == skip_mutex_handle) {
02157 skip_mutex_handle = -1;
02158 return SS_SUCCESS;
02159 }
02160
02161 do {
02162 status = semop(mutex_handle, &sb, 1);
02163
02164
02165 if (status == 0)
02166 break;
02167
02168
02169 if (errno == EINTR)
02170 continue;
02171
02172 return SS_NO_MUTEX;
02173 } while (1);
02174
02175 return SS_SUCCESS;
02176 }
02177 #endif
02178
02179 #ifdef OS_MSDOS
02180 return SS_NO_MUTEX;
02181 #endif
02182 }
02183
02184
02185 INT ss_mutex_delete(HNDLE mutex_handle, INT destroy_flag)
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203 {
02204 #ifdef OS_WINNT
02205
02206 if (CloseHandle((HANDLE) mutex_handle) == FALSE)
02207 return SS_NO_MUTEX;
02208
02209 return SS_SUCCESS;
02210
02211 #endif
02212 #ifdef OS_VMS
02213
02214 free((void *) mutex_handle);
02215 return SS_SUCCESS;
02216
02217 #endif
02218
02219 #ifdef OS_VXWORKS
02220
02221 if (semDelete((SEM_ID) mutex_handle) == ERROR)
02222 return SS_NO_MUTEX;
02223 return SS_SUCCESS;
02224 #endif
02225
02226 #ifdef OS_UNIX
02227 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(OS_FREEBSD)
02228 union semun arg;
02229 #else
02230 union semun {
02231 INT val;
02232 struct semid_ds *buf;
02233 ushort *array;
02234 } arg;
02235 #endif
02236
02237 memset(&arg, 0, sizeof(arg));
02238
02239 if (destroy_flag)
02240 if (semctl(mutex_handle, 0, IPC_RMID, arg) < 0)
02241 return SS_NO_MUTEX;
02242
02243 return SS_SUCCESS;
02244
02245 #endif
02246
02247 #ifdef OS_MSDOS
02248 return SS_NO_MUTEX;
02249 #endif
02250 }
02251
02252
02253 #endif
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273 DWORD ss_millitime()
02274 {
02275 #ifdef OS_WINNT
02276
02277 return (int) GetTickCount();
02278
02279 #endif
02280 #ifdef OS_MSDOS
02281
02282 return clock() * 55;
02283
02284 #endif
02285 #ifdef OS_VMS
02286
02287 {
02288 char time[8];
02289 DWORD lo, hi;
02290
02291 sys$gettim(time);
02292
02293 lo = *((DWORD *) time);
02294 hi = *((DWORD *) (time + 4));
02295
02296
02297
02298 return lo / 10000 + hi * 429496.7296;
02299
02300 }
02301
02302 #endif
02303 #ifdef OS_UNIX
02304 {
02305 struct timeval tv;
02306
02307 gettimeofday(&tv, NULL);
02308
02309 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
02310 }
02311
02312 #endif
02313 #ifdef OS_VXWORKS
02314 {
02315 int count;
02316 static int ticks_per_msec = 0;
02317
02318 if (ticks_per_msec == 0)
02319 ticks_per_msec = 1000 / sysClkRateGet();
02320
02321 return tickGet() * ticks_per_msec;
02322 }
02323 #endif
02324 }
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340 DWORD ss_time()
02341 {
02342 #if !defined(OS_VXWORKS)
02343 #if !defined(OS_VMS)
02344 tzset();
02345 #endif
02346 #endif
02347 return (DWORD) time(NULL);
02348 }
02349
02350
02351 #ifndef DOXYGEN_SHOULD_SKIP_THIS
02352
02353
02354 DWORD ss_settime(DWORD seconds)
02355
02356
02357
02358
02359
02360
02361
02362
02363
02364
02365
02366
02367
02368
02369
02370 {
02371 #if defined(OS_WINNT)
02372 SYSTEMTIME st;
02373 struct tm *ltm;
02374
02375 tzset();
02376 ltm = localtime((time_t *) & seconds);
02377
02378 st.wYear = ltm->tm_year + 1900;
02379 st.wMonth = ltm->tm_mon + 1;
02380 st.wDay = ltm->tm_mday;
02381 st.wHour = ltm->tm_hour;
02382 st.wMinute = ltm->tm_min;
02383 st.wSecond = ltm->tm_sec;
02384 st.wMilliseconds = 0;
02385
02386 SetLocalTime(&st);
02387
02388 #elif defined(OS_DARWIN)
02389
02390 assert(!"ss_settime() is not supported");
02391
02392 return SS_NO_DRIVER;
02393
02394 #elif defined(OS_UNIX)
02395
02396 stime((time_t *) & seconds);
02397
02398 #elif defined(OS_VXWORKS)
02399
02400 struct timespec ltm;
02401
02402 ltm.tv_sec = seconds;
02403 ltm.tv_nsec = 0;
02404 clock_settime(CLOCK_REALTIME, <m);
02405
02406 #endif
02407 return SS_SUCCESS;
02408 }
02409
02410
02411 char *ss_asctime()
02412
02413
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428 {
02429 static char str[32];
02430 time_t seconds;
02431
02432 seconds = (time_t) ss_time();
02433
02434 #if !defined(OS_VXWORKS)
02435 #if !defined(OS_VMS)
02436 tzset();
02437 #endif
02438 #endif
02439 strcpy(str, asctime(localtime(&seconds)));
02440
02441
02442 str[24] = 0;
02443
02444 return str;
02445 }
02446
02447
02448 INT ss_timezone()
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466 {
02467 #if defined(OS_DARWIN) || defined(OS_VXWORKS)
02468 return 0;
02469 #else
02470 return timezone;
02471 #endif
02472 }
02473
02474
02475
02476
02477 #ifdef OS_UNIX
02478
02479 void ss_cont()
02480 {
02481 }
02482 #endif
02483
02484
02485 #endif
02486
02487
02488
02489
02490
02491
02492
02493
02494
02495
02496
02497
02498
02499 INT ss_sleep(INT millisec)
02500 {
02501 fd_set readfds;
02502 struct timeval timeout;
02503 int status;
02504 static int sock = 0;
02505
02506 if (millisec == 0) {
02507 #ifdef OS_WINNT
02508 SuspendThread(GetCurrentThread());
02509 #endif
02510 #ifdef OS_VMS
02511 sys$hiber();
02512 #endif
02513 #ifdef OS_UNIX
02514 signal(SIGCONT, ss_cont);
02515 pause();
02516 #endif
02517 return SS_SUCCESS;
02518 }
02519 #ifdef OS_WINNT
02520 {
02521 WSADATA WSAData;
02522
02523
02524 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
02525 return SS_SOCKET_ERROR;
02526 }
02527 #endif
02528
02529 timeout.tv_sec = millisec / 1000;
02530 timeout.tv_usec = (millisec % 1000) * 1000;
02531
02532 if (!sock)
02533 sock = socket(AF_INET, SOCK_DGRAM, 0);
02534
02535 FD_ZERO(&readfds);
02536 FD_SET(sock, &readfds);
02537 do {
02538 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
02539
02540
02541 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
02542 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
02543
02544 } while (status == -1);
02545
02546 return SS_SUCCESS;
02547 }
02548
02549
02550 #ifndef DOXYGEN_SHOULD_SKIP_THIS
02551
02552
02553 BOOL ss_kbhit()
02554
02555
02556
02557
02558
02559
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571 {
02572 #ifdef OS_MSDOS
02573
02574 return kbhit();
02575
02576 #endif
02577 #ifdef OS_WINNT
02578
02579 return kbhit();
02580
02581 #endif
02582 #ifdef OS_VMS
02583
02584 return FALSE;
02585
02586 #endif
02587 #ifdef OS_UNIX
02588
02589 int n;
02590
02591 if (_daemon_flag)
02592 return 0;
02593
02594 ioctl(0, FIONREAD, &n);
02595 return (n > 0);
02596
02597 #endif
02598 #ifdef OS_VXWORKS
02599
02600 int n;
02601 ioctl(0, FIONREAD, (long) &n);
02602 return (n > 0);
02603
02604 #endif
02605 }
02606
02607
02608
02609 #ifdef LOCAL_ROUTINES
02610
02611 INT ss_wake(INT pid, INT tid, INT thandle)
02612
02613
02614
02615
02616
02617
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633 {
02634 #ifdef OS_WINNT
02635 HANDLE process_handle;
02636 HANDLE dup_thread_handle;
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646
02647 process_handle = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
02648
02649 if (process_handle == 0)
02650 return SS_NO_PROCESS;
02651
02652 DuplicateHandle(process_handle, (HANDLE) thandle, GetCurrentProcess(),
02653 &dup_thread_handle, THREAD_ALL_ACCESS, TRUE, 0);
02654
02655
02656 CloseHandle(process_handle);
02657
02658 if (dup_thread_handle == 0)
02659 return SS_NO_PROCESS;
02660
02661 ResumeThread(dup_thread_handle);
02662
02663
02664 CloseHandle(dup_thread_handle);
02665
02666 return SS_SUCCESS;
02667
02668 #endif
02669 #ifdef OS_VMS
02670
02671 if (sys$wake(&pid, 0) == SS$_NONEXPR)
02672 return SS_NO_PROCESS;
02673
02674 return SS_SUCCESS;
02675
02676 #endif
02677 #ifdef OS_UNIX
02678
02679 if (kill(pid, SIGCONT) < 0)
02680 return SS_NO_PROCESS;
02681
02682 return SS_SUCCESS;
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692 #endif
02693 }
02694
02695
02696 #ifdef OS_WINNT
02697
02698 static void (*UserCallback) (int);
02699 static UINT _timer_id = 0;
02700
02701 VOID CALLBACK _timeCallback(UINT idEvent, UINT uReserved, DWORD dwUser,
02702 DWORD dwReserved1, DWORD dwReserved2)
02703 {
02704 _timer_id = 0;
02705 if (UserCallback != NULL)
02706 UserCallback(0);
02707 }
02708
02709 #endif
02710
02711 INT ss_alarm(INT millitime, void (*func) (int))
02712
02713
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726
02727
02728
02729
02730
02731 {
02732 #ifdef OS_WINNT
02733
02734 UserCallback = func;
02735 if (millitime > 0)
02736 _timer_id =
02737 timeSetEvent(millitime, 100, (LPTIMECALLBACK) _timeCallback, 0, TIME_ONESHOT);
02738 else {
02739 if (_timer_id)
02740 timeKillEvent(_timer_id);
02741 _timer_id = 0;
02742 }
02743
02744 return SS_SUCCESS;
02745
02746 #endif
02747 #ifdef OS_VMS
02748
02749 signal(SIGALRM, func);
02750 alarm(millitime / 1000);
02751 return SS_SUCCESS;
02752
02753 #endif
02754 #ifdef OS_UNIX
02755
02756 signal(SIGALRM, func);
02757 alarm(millitime / 1000);
02758 return SS_SUCCESS;
02759
02760 #endif
02761 }
02762
02763
02764 void (*MidasExceptionHandler) ();
02765
02766 #ifdef OS_WINNT
02767
02768 LONG MidasExceptionFilter(LPEXCEPTION_POINTERS pexcep)
02769 {
02770 if (MidasExceptionHandler != NULL)
02771 MidasExceptionHandler();
02772
02773 return EXCEPTION_CONTINUE_SEARCH;
02774 }
02775
02776 INT MidasExceptionSignal(INT sig)
02777 {
02778 if (MidasExceptionHandler != NULL)
02779 MidasExceptionHandler();
02780
02781 raise(sig);
02782
02783 return 0;
02784 }
02785
02786
02787
02788
02789
02790
02791
02792
02793
02794
02795
02796 #endif
02797
02798 #ifdef OS_VMS
02799
02800 INT MidasExceptionFilter(INT * sigargs, INT * mechargs)
02801 {
02802 if (MidasExceptionHandler != NULL)
02803 MidasExceptionHandler();
02804
02805 return (SS$_RESIGNAL);
02806 }
02807
02808 void MidasExceptionSignal(INT sig)
02809 {
02810 if (MidasExceptionHandler != NULL)
02811 MidasExceptionHandler();
02812
02813 kill(getpid(), sig);
02814 }
02815
02816 #endif
02817
02818
02819 INT ss_exception_handler(void (*func) ())
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838 {
02839 #ifdef OS_WINNT
02840
02841 MidasExceptionHandler = func;
02842
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853 #endif
02854 #ifdef OS_VMS
02855
02856 MidasExceptionHandler = func;
02857 lib$establish(MidasExceptionFilter);
02858
02859 signal(SIGINT, MidasExceptionSignal);
02860 signal(SIGILL, MidasExceptionSignal);
02861 signal(SIGQUIT, MidasExceptionSignal);
02862 signal(SIGFPE, MidasExceptionSignal);
02863 signal(SIGSEGV, MidasExceptionSignal);
02864 signal(SIGTERM, MidasExceptionSignal);
02865
02866 #endif
02867
02868 return SS_SUCCESS;
02869 }
02870
02871 #endif
02872
02873
02874 void *ss_ctrlc_handler(void (*func) (int))
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894 {
02895 #ifdef OS_WINNT
02896
02897 if (func == NULL) {
02898 signal(SIGBREAK, SIG_DFL);
02899 return signal(SIGINT, SIG_DFL);
02900 } else {
02901 signal(SIGBREAK, func);
02902 return signal(SIGINT, func);
02903 }
02904 return NULL;
02905
02906 #endif
02907 #ifdef OS_VMS
02908
02909 return signal(SIGINT, func);
02910
02911 #endif
02912
02913 #ifdef OS_UNIX
02914
02915 if (func == NULL) {
02916 signal(SIGTERM, SIG_DFL);
02917 return (void *) signal(SIGINT, SIG_DFL);
02918 } else {
02919 signal(SIGTERM, func);
02920 return (void *) signal(SIGINT, func);
02921 }
02922
02923 #endif
02924 }
02925
02926
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943
02944 typedef struct {
02945 BOOL in_use;
02946 INT thread_id;
02947 INT ipc_port;
02948 INT ipc_recv_socket;
02949 INT ipc_send_socket;
02950 INT(*ipc_dispatch) (char *, INT);
02951 INT listen_socket;
02952 INT(*listen_dispatch) (INT);
02953 RPC_SERVER_CONNECTION *server_connection;
02954 INT(*client_dispatch) (INT);
02955 RPC_SERVER_ACCEPTION *server_acception;
02956 INT(*server_dispatch) (INT, int, BOOL);
02957 struct sockaddr_in bind_addr;
02958 } SUSPEND_STRUCT;
02959
02960 SUSPEND_STRUCT *_suspend_struct = NULL;
02961 INT _suspend_entries;
02962
02963
02964 INT ss_suspend_init_ipc(INT index)
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976
02977
02978
02979
02980
02981
02982
02983 {
02984 INT status, sock;
02985 int i;
02986 struct sockaddr_in bind_addr;
02987 char local_host_name[HOST_NAME_LENGTH];
02988 struct hostent *phe;
02989
02990 #ifdef OS_WINNT
02991 {
02992 WSADATA WSAData;
02993
02994
02995 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
02996 return SS_SOCKET_ERROR;
02997 }
02998 #endif
02999
03000
03001 sock = socket(AF_INET, SOCK_DGRAM, 0);
03002 if (sock == -1)
03003 return SS_SOCKET_ERROR;
03004
03005
03006 memset(&bind_addr, 0, sizeof(bind_addr));
03007 bind_addr.sin_family = AF_INET;
03008 bind_addr.sin_addr.s_addr = 0;
03009 bind_addr.sin_port = 0;
03010
03011 gethostname(local_host_name, sizeof(local_host_name));
03012
03013 #ifdef OS_VXWORKS
03014 {
03015 INT host_addr;
03016
03017 host_addr = hostGetByName(local_host_name);
03018 memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
03019 }
03020 #else
03021 phe = gethostbyname(local_host_name);
03022 if (phe == NULL) {
03023 cm_msg(MERROR, "ss_suspend_init_ipc", "cannot get host name");
03024 return SS_SOCKET_ERROR;
03025 }
03026 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
03027 #endif
03028
03029 status = bind(sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
03030 if (status < 0)
03031 return SS_SOCKET_ERROR;
03032
03033
03034 i = sizeof(bind_addr);
03035 getsockname(sock, (struct sockaddr *) &bind_addr, (int *) &i);
03036
03037 _suspend_struct[index].ipc_recv_socket = sock;
03038 _suspend_struct[index].ipc_port = ntohs(bind_addr.sin_port);
03039
03040
03041 sock = socket(AF_INET, SOCK_DGRAM, 0);
03042
03043 if (sock == -1)
03044 return SS_SOCKET_ERROR;
03045
03046
03047 memset(&bind_addr, 0, sizeof(bind_addr));
03048 bind_addr.sin_family = AF_INET;
03049 bind_addr.sin_addr.s_addr = 0;
03050
03051 #ifdef OS_VXWORKS
03052 {
03053 INT host_addr;
03054
03055 host_addr = hostGetByName(local_host_name);
03056 memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
03057 }
03058 #else
03059 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
03060 #endif
03061
03062 memcpy(&_suspend_struct[index].bind_addr, &bind_addr, sizeof(bind_addr));
03063 _suspend_struct[index].ipc_send_socket = sock;
03064
03065 return SS_SUCCESS;
03066 }
03067
03068
03069 INT ss_suspend_get_index(INT * pindex)
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088
03089 {
03090 INT index;
03091
03092 if (_suspend_struct == NULL) {
03093
03094 _suspend_struct = (SUSPEND_STRUCT *) malloc(sizeof(SUSPEND_STRUCT));
03095 memset(_suspend_struct, 0, sizeof(SUSPEND_STRUCT));
03096 if (_suspend_struct == NULL)
03097 return SS_NO_MEMORY;
03098
03099 _suspend_entries = 1;
03100 *pindex = 0;
03101 _suspend_struct[0].thread_id = ss_gettid();
03102 _suspend_struct[0].in_use = TRUE;
03103 } else {
03104
03105 for (index = 0; index < _suspend_entries; index++)
03106 if (_suspend_struct[index].thread_id == ss_gettid()) {
03107 if (pindex != NULL)
03108 *pindex = index;
03109
03110 return SS_SUCCESS;
03111 }
03112
03113
03114 for (index = 0; index < _suspend_entries; index++)
03115 if (!_suspend_struct[index].in_use)
03116 break;
03117
03118 if (index == _suspend_entries) {
03119
03120 _suspend_struct = (SUSPEND_STRUCT *) realloc(_suspend_struct,
03121 sizeof
03122 (SUSPEND_STRUCT) *
03123 (_suspend_entries + 1));
03124 memset(&_suspend_struct[_suspend_entries], 0, sizeof(SUSPEND_STRUCT));
03125
03126 _suspend_entries++;
03127 if (_suspend_struct == NULL) {
03128 _suspend_entries--;
03129 return SS_NO_MEMORY;
03130 }
03131 }
03132 *pindex = index;
03133 _suspend_struct[index].thread_id = ss_gettid();
03134 _suspend_struct[index].in_use = TRUE;
03135 }
03136
03137 return SS_SUCCESS;
03138 }
03139
03140
03141 INT ss_suspend_exit()
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159 {
03160 INT i, status;
03161
03162 status = ss_suspend_get_index(&i);
03163
03164 if (status != SS_SUCCESS)
03165 return status;
03166
03167 if (_suspend_struct[i].ipc_recv_socket) {
03168 closesocket(_suspend_struct[i].ipc_recv_socket);
03169 closesocket(_suspend_struct[i].ipc_send_socket);
03170 }
03171
03172 memset(&_suspend_struct[i], 0, sizeof(SUSPEND_STRUCT));
03173
03174
03175 for (i = _suspend_entries - 1; i >= 0; i--)
03176 if (_suspend_struct[i].in_use)
03177 break;
03178
03179 _suspend_entries = i + 1;
03180
03181 if (_suspend_entries == 0) {
03182 free(_suspend_struct);
03183 _suspend_struct = NULL;
03184 }
03185
03186 return SS_SUCCESS;
03187 }
03188
03189
03190 INT ss_suspend_set_dispatch(INT channel, void *connection, INT(*dispatch) ())
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218
03219 {
03220 INT i, status;
03221
03222 status = ss_suspend_get_index(&i);
03223
03224 if (status != SS_SUCCESS)
03225 return status;
03226
03227 if (channel == CH_IPC) {
03228 _suspend_struct[i].ipc_dispatch = (INT(*)(char *, INT)) dispatch;
03229
03230 if (!_suspend_struct[i].ipc_recv_socket)
03231 ss_suspend_init_ipc(i);
03232 }
03233
03234 if (channel == CH_LISTEN) {
03235 _suspend_struct[i].listen_socket = *((INT *) connection);
03236 _suspend_struct[i].listen_dispatch = (INT(*)(INT)) dispatch;
03237 }
03238
03239 if (channel == CH_CLIENT) {
03240 _suspend_struct[i].server_connection = (RPC_SERVER_CONNECTION *) connection;
03241 _suspend_struct[i].client_dispatch = (INT(*)(INT)) dispatch;
03242 }
03243
03244 if (channel == CH_SERVER) {
03245 _suspend_struct[i].server_acception = (RPC_SERVER_ACCEPTION *) connection;
03246 _suspend_struct[i].server_dispatch = (INT(*)(INT, int, BOOL)) dispatch;
03247 }
03248
03249 return SS_SUCCESS;
03250 }
03251
03252
03253 INT ss_suspend_get_port(INT * port)
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274 {
03275 INT index, status;
03276
03277 status = ss_suspend_get_index(&index);
03278
03279 if (status != SS_SUCCESS)
03280 return status;
03281
03282 if (!_suspend_struct[index].ipc_port)
03283 ss_suspend_init_ipc(index);
03284
03285 *port = _suspend_struct[index].ipc_port;
03286
03287 return SS_SUCCESS;
03288 }
03289
03290
03291 INT ss_suspend(INT millisec, INT msg)
03292
03293
03294
03295
03296
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308
03309
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322 {
03323 fd_set readfds;
03324 struct timeval timeout;
03325 INT sock, server_socket;
03326 INT index, status, i, return_status;
03327 int size;
03328 struct sockaddr from_addr;
03329 char str[100], buffer[80], buffer_tmp[80];
03330
03331
03332 status = ss_suspend_get_index(&index);
03333
03334 if (status != SS_SUCCESS)
03335 return status;
03336
03337 return_status = SS_TIMEOUT;
03338
03339 do {
03340 FD_ZERO(&readfds);
03341
03342
03343 if (_suspend_struct[index].listen_socket)
03344 FD_SET(_suspend_struct[index].listen_socket, &readfds);
03345
03346
03347 if (_suspend_struct[index].server_acception)
03348 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03349
03350 sock = _suspend_struct[index].server_acception[i].recv_sock;
03351
03352
03353 if (!sock || _suspend_struct[index].server_acception[i].tid != ss_gettid())
03354 continue;
03355
03356
03357 if (recv_tcp_check(sock) == 0)
03358 FD_SET(sock, &readfds);
03359
03360
03361 else if (msg == 0)
03362 millisec = 0;
03363
03364
03365 sock = _suspend_struct[index].server_acception[i].event_sock;
03366
03367 if (!sock)
03368 continue;
03369
03370
03371 if (recv_event_check(sock) == 0)
03372 FD_SET(sock, &readfds);
03373
03374
03375 else if (msg == 0)
03376 millisec = 0;
03377 }
03378
03379
03380 if (_suspend_struct[index].server_connection) {
03381 sock = _suspend_struct[index].server_connection->recv_sock;
03382 if (sock)
03383 FD_SET(sock, &readfds);
03384 }
03385
03386
03387 if (_suspend_struct[index].ipc_recv_socket)
03388 FD_SET(_suspend_struct[index].ipc_recv_socket, &readfds);
03389
03390 timeout.tv_sec = millisec / 1000;
03391 timeout.tv_usec = (millisec % 1000) * 1000;
03392
03393 do {
03394 if (millisec < 0)
03395 status = select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
03396 else
03397 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03398
03399
03400 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
03401 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
03402
03403 } while (status == -1);
03404
03405
03406 if (_suspend_struct[index].listen_socket &&
03407 FD_ISSET(_suspend_struct[index].listen_socket, &readfds)) {
03408 sock = _suspend_struct[index].listen_socket;
03409
03410 if (_suspend_struct[index].listen_dispatch) {
03411 status = _suspend_struct[index].listen_dispatch(sock);
03412 if (status == RPC_SHUTDOWN)
03413 return status;
03414 }
03415 }
03416
03417
03418 if (_suspend_struct[index].server_acception)
03419 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03420
03421 sock = _suspend_struct[index].server_acception[i].recv_sock;
03422
03423
03424 if (!sock || _suspend_struct[index].server_acception[i].tid != ss_gettid())
03425 continue;
03426
03427 if (recv_tcp_check(sock) || FD_ISSET(sock, &readfds)) {
03428 if (_suspend_struct[index].server_dispatch) {
03429 status = _suspend_struct[index].server_dispatch(i, sock, msg != 0);
03430 _suspend_struct[index].server_acception[i].
03431 last_activity = ss_millitime();
03432
03433 if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN)
03434 return status;
03435
03436 return_status = SS_SERVER_RECV;
03437 }
03438 }
03439
03440
03441 sock = _suspend_struct[index].server_acception[i].event_sock;
03442 if (!sock)
03443 continue;
03444
03445 if (recv_event_check(sock) || FD_ISSET(sock, &readfds)) {
03446 if (_suspend_struct[index].server_dispatch) {
03447 status = _suspend_struct[index].server_dispatch(i, sock, msg != 0);
03448 _suspend_struct[index].server_acception[i].
03449 last_activity = ss_millitime();
03450
03451 if (status == SS_ABORT || status == SS_EXIT || status == RPC_SHUTDOWN)
03452 return status;
03453
03454 return_status = SS_SERVER_RECV;
03455 }
03456 }
03457 }
03458
03459
03460 if (_suspend_struct[index].server_connection) {
03461 sock = _suspend_struct[index].server_connection->recv_sock;
03462
03463 if (sock && FD_ISSET(sock, &readfds)) {
03464 if (_suspend_struct[index].client_dispatch)
03465 status = _suspend_struct[index].client_dispatch(sock);
03466 else {
03467 status = SS_SUCCESS;
03468 size = recv_tcp(sock, buffer, sizeof(buffer), 0);
03469
03470 if (size <= 0)
03471 status = SS_ABORT;
03472 }
03473
03474 if (status == SS_ABORT) {
03475 sprintf(str, "Server connection broken to %s",
03476 _suspend_struct[index].server_connection->host_name);
03477 cm_msg(MINFO, "ss_suspend", str);
03478
03479
03480 closesocket(_suspend_struct[index].server_connection->send_sock);
03481 closesocket(_suspend_struct[index].server_connection->recv_sock);
03482 closesocket(_suspend_struct[index].server_connection->event_sock);
03483
03484 memset(_suspend_struct[index].server_connection,
03485 0, sizeof(RPC_CLIENT_CONNECTION));
03486
03487
03488 return SS_ABORT;
03489 }
03490
03491 return_status = SS_CLIENT_RECV;
03492 }
03493 }
03494
03495
03496 if (_suspend_struct[index].ipc_recv_socket &&
03497 FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds)) {
03498
03499 size = sizeof(struct sockaddr);
03500 size = recvfrom(_suspend_struct[index].ipc_recv_socket,
03501 buffer, sizeof(buffer), 0, &from_addr, (int *) &size);
03502
03503
03504 server_socket = 0;
03505 if (_suspend_struct[index].server_acception &&
03506 rpc_get_server_option(RPC_OSERVER_TYPE) != ST_REMOTE)
03507 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03508 sock = _suspend_struct[index].server_acception[i].send_sock;
03509 if (sock && _suspend_struct[index].server_acception[i].tid == ss_gettid())
03510 server_socket = sock;
03511 }
03512
03513
03514 do {
03515 FD_ZERO(&readfds);
03516 FD_SET(_suspend_struct[index].ipc_recv_socket, &readfds);
03517
03518 timeout.tv_sec = 0;
03519 timeout.tv_usec = 0;
03520
03521 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03522
03523 if (status != -1
03524 && FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds)) {
03525 size = sizeof(struct sockaddr);
03526 size =
03527 recvfrom(_suspend_struct[index].ipc_recv_socket,
03528 buffer_tmp, sizeof(buffer_tmp), 0, &from_addr, &size);
03529
03530
03531 if (buffer_tmp[0] != 'B' || strcmp(buffer_tmp, buffer) != 0)
03532 if (_suspend_struct[index].ipc_dispatch)
03533 _suspend_struct[index].ipc_dispatch(buffer_tmp, server_socket);
03534 }
03535
03536 } while (FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds));
03537
03538
03539 if (msg == MSG_BM && buffer[0] == 'B')
03540 return SS_SUCCESS;
03541 if (msg == MSG_ODB && buffer[0] == 'O')
03542 return SS_SUCCESS;
03543
03544
03545 if (_suspend_struct[index].ipc_dispatch)
03546 _suspend_struct[index].ipc_dispatch(buffer, server_socket);
03547
03548 return_status = SS_SUCCESS;
03549 }
03550
03551 } while (millisec < 0);
03552
03553 return return_status;
03554 }
03555
03556
03557 INT ss_resume(INT port, char *message)
03558
03559
03560
03561
03562
03563
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573
03574
03575
03576
03577
03578
03579
03580 {
03581 INT status, index;
03582
03583 if (ss_in_async_routine_flag) {
03584
03585 index = 0;
03586 } else {
03587 status = ss_suspend_get_index(&index);
03588
03589 if (status != SS_SUCCESS)
03590 return status;
03591 }
03592
03593 _suspend_struct[index].bind_addr.sin_port = htons((short) port);
03594
03595 status = sendto(_suspend_struct[index].ipc_send_socket, message,
03596 strlen(message) + 1, 0,
03597 (struct sockaddr *) &_suspend_struct[index].bind_addr,
03598 sizeof(struct sockaddr_in));
03599
03600 if (status != (INT) strlen(message) + 1)
03601 return SS_SOCKET_ERROR;
03602
03603 return SS_SUCCESS;
03604 }
03605
03606
03607
03608
03609
03610
03611
03612
03613
03614 INT send_tcp(int sock, char *buffer, DWORD buffer_size, INT flags)
03615
03616
03617
03618
03619
03620
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634 {
03635 DWORD count;
03636 INT status;
03637
03638
03639
03640 for (count = 0; (INT) count < (INT) buffer_size - NET_TCP_SIZE;) {
03641 status = send(sock, buffer + count, NET_TCP_SIZE, flags);
03642 if (status != -1)
03643 count += status;
03644 else {
03645 cm_msg(MERROR, "send_tcp",
03646 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
03647 sock, NET_TCP_SIZE, status, errno, strerror(errno));
03648 return status;
03649 }
03650 }
03651
03652 while (count < buffer_size) {
03653 status = send(sock, buffer + count, buffer_size - count, flags);
03654 if (status != -1)
03655 count += status;
03656 else {
03657 cm_msg(MERROR, "send_tcp",
03658 "send(socket=%d,size=%d) returned %d, errno: %d (%s)",
03659 sock, (int) (buffer_size - count), status, errno, strerror(errno));
03660 return status;
03661 }
03662 }
03663
03664 return count;
03665 }
03666
03667
03668 INT recv_string(int sock, char *buffer, DWORD buffer_size, INT millisec)
03669
03670
03671
03672
03673
03674
03675
03676
03677
03678
03679
03680
03681
03682
03683
03684
03685
03686
03687
03688
03689
03690
03691
03692
03693 {
03694 INT i, status;
03695 DWORD n;
03696 fd_set readfds;
03697 struct timeval timeout;
03698
03699 n = 0;
03700 memset(buffer, 0, buffer_size);
03701
03702 do {
03703 if (millisec > 0) {
03704 FD_ZERO(&readfds);
03705 FD_SET(sock, &readfds);
03706
03707 timeout.tv_sec = millisec / 1000;
03708 timeout.tv_usec = (millisec % 1000) * 1000;
03709
03710 do {
03711 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03712
03713
03714 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
03715 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
03716
03717 } while (status == -1);
03718
03719 if (!FD_ISSET(sock, &readfds))
03720 break;
03721 }
03722
03723 i = recv(sock, buffer + n, 1, 0);
03724
03725 if (i <= 0)
03726 break;
03727
03728 n++;
03729
03730 if (n >= buffer_size)
03731 break;
03732
03733 } while (buffer[n - 1] && buffer[n - 1] != 10);
03734
03735 return n - 1;
03736 }
03737
03738
03739 INT recv_tcp(int sock, char *net_buffer, DWORD buffer_size, INT flags)
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755
03756
03757
03758
03759
03760
03761
03762
03763
03764
03765
03766
03767
03768
03769 {
03770 INT param_size, n_received, n;
03771 NET_COMMAND *nc;
03772
03773 if (buffer_size < sizeof(NET_COMMAND_HEADER)) {
03774 cm_msg(MERROR, "recv_tcp", "parameters too large for network buffer");
03775 return -1;
03776 }
03777
03778
03779 n_received = 0;
03780 do {
03781 #ifdef OS_UNIX
03782 do {
03783 n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
03784
03785
03786 } while (n == -1 && errno == EINTR);
03787 #else
03788 n = recv(sock, net_buffer + n_received, sizeof(NET_COMMAND_HEADER), flags);
03789 #endif
03790
03791 if (n <= 0) {
03792 cm_msg(MERROR, "recv_tcp",
03793 "header: recv returned %d, n_received = %d, errno: %d (%s)",
03794 n, n_received, errno, strerror(errno));
03795 return n;
03796 }
03797
03798 n_received += n;
03799
03800 } while (n_received < sizeof(NET_COMMAND_HEADER));
03801
03802
03803
03804 nc = (NET_COMMAND *) net_buffer;
03805 param_size = nc->header.param_size;
03806 n_received = 0;
03807
03808 if (param_size == 0)
03809 return sizeof(NET_COMMAND_HEADER);
03810
03811 do {
03812 #ifdef OS_UNIX
03813 do {
03814 n = recv(sock,
03815 net_buffer + sizeof(NET_COMMAND_HEADER) + n_received,
03816 param_size - n_received, flags);
03817
03818
03819 } while (n == -1 && errno == EINTR);
03820 #else
03821 n = recv(sock, net_buffer + sizeof(NET_COMMAND_HEADER) + n_received,
03822 param_size - n_received, flags);
03823 #endif
03824
03825 if (n <= 0) {
03826 cm_msg(MERROR, "recv_tcp",
03827 "param: recv returned %d, n_received = %d, errno: %d (%s)",
03828 n, n_received, errno, strerror(errno));
03829 return n;
03830 }
03831
03832 n_received += n;
03833 } while (n_received < param_size);
03834
03835 return sizeof(NET_COMMAND_HEADER) + param_size;
03836 }
03837
03838
03839 INT send_udp(int sock, char *buffer, DWORD buffer_size, INT flags)
03840
03841
03842
03843
03844
03845
03846
03847
03848
03849
03850
03851
03852
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862 {
03863 INT status;
03864 UDP_HEADER *udp_header;
03865 static char udp_buffer[NET_UDP_SIZE];
03866 static INT serial_number = 0, n_received = 0;
03867 DWORD i, data_size;
03868
03869 udp_header = (UDP_HEADER *) udp_buffer;
03870 data_size = NET_UDP_SIZE - sizeof(UDP_HEADER);
03871
03872
03873
03874
03875
03876 if (buffer_size >= NET_UDP_SIZE / 2 && buffer_size <= data_size) {
03877
03878
03879
03880 if (n_received) {
03881 udp_header->serial_number = UDP_FIRST | n_received;
03882 udp_header->sequence_number = ++serial_number;
03883
03884 send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03885 n_received = 0;
03886 }
03887
03888 udp_header->serial_number = UDP_FIRST | buffer_size;
03889 udp_header->sequence_number = ++serial_number;
03890
03891 memcpy(udp_header + 1, buffer, buffer_size);
03892 status = send(sock, udp_buffer, buffer_size + sizeof(UDP_HEADER), flags);
03893 if (status == (INT) buffer_size + (int) sizeof(UDP_HEADER))
03894 status -= sizeof(UDP_HEADER);
03895
03896 return status;
03897 }
03898
03899
03900
03901
03902
03903 if (buffer_size <= data_size) {
03904
03905 if (buffer_size + n_received < data_size) {
03906 memcpy(udp_buffer + sizeof(UDP_HEADER) + n_received, buffer, buffer_size);
03907
03908 n_received += buffer_size;
03909 return buffer_size;
03910 }
03911
03912
03913 udp_header->serial_number = UDP_FIRST | n_received;
03914 udp_header->sequence_number = ++serial_number;
03915
03916 status = send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03917
03918 n_received = 0;
03919
03920 memcpy(udp_header + 1, buffer, buffer_size);
03921 n_received = buffer_size;
03922
03923 return buffer_size;
03924 }
03925
03926
03927
03928
03929
03930
03931
03932 if (n_received) {
03933 udp_header->serial_number = UDP_FIRST | n_received;
03934 udp_header->sequence_number = ++serial_number;
03935
03936 send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03937 n_received = 0;
03938 }
03939
03940 for (i = 0; i < ((buffer_size - 1) / data_size); i++) {
03941 if (i == 0) {
03942 udp_header->serial_number = UDP_FIRST | buffer_size;
03943 udp_header->sequence_number = ++serial_number;
03944 } else {
03945 udp_header->serial_number = serial_number;
03946 udp_header->sequence_number = i;
03947 }
03948
03949 memcpy(udp_header + 1, buffer + i * data_size, data_size);
03950 send(sock, udp_buffer, NET_UDP_SIZE, flags);
03951 }
03952
03953
03954 udp_header->serial_number = serial_number;
03955 udp_header->sequence_number = i;
03956 memcpy(udp_header + 1, buffer + i * data_size, buffer_size - i * data_size);
03957 status =
03958 send(sock, udp_buffer, sizeof(UDP_HEADER) + buffer_size - i * data_size, flags);
03959 if ((DWORD) status == sizeof(UDP_HEADER) + buffer_size - i * data_size)
03960 return buffer_size;
03961
03962 return status;
03963 }
03964
03965
03966 INT recv_udp(int sock, char *buffer, DWORD buffer_size, INT flags)
03967
03968
03969
03970
03971
03972
03973
03974
03975
03976
03977
03978
03979
03980
03981
03982
03983
03984
03985
03986
03987
03988 {
03989 INT i, status;
03990 UDP_HEADER *udp_header;
03991 char udp_buffer[NET_UDP_SIZE];
03992 DWORD serial_number, sequence_number, total_buffer_size;
03993 DWORD data_size, n_received;
03994 fd_set readfds;
03995 struct timeval timeout;
03996
03997 udp_header = (UDP_HEADER *) udp_buffer;
03998 data_size = NET_UDP_SIZE - sizeof(UDP_HEADER);
03999
04000
04001 #ifdef OS_UNIX
04002 do {
04003 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04004
04005
04006 } while (i == -1 && errno == EINTR);
04007 #else
04008 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04009 #endif
04010
04011 start:
04012
04013
04014 while (!(udp_header->serial_number & UDP_FIRST)) {
04015
04016 FD_ZERO(&readfds);
04017 FD_SET(sock, &readfds);
04018
04019 timeout.tv_sec = 0;
04020 timeout.tv_usec = 100000;
04021
04022 do {
04023 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
04024 } while (status == -1);
04025
04026
04027
04028
04029
04030 if (!FD_ISSET(sock, &readfds))
04031 return 0;
04032
04033 #ifdef OS_UNIX
04034 do {
04035 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04036
04037
04038 } while (i == -1 && errno == EINTR);
04039 #else
04040 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04041 #endif
04042 }
04043
04044
04045 total_buffer_size = udp_header->serial_number & ~UDP_FIRST;
04046 serial_number = udp_header->sequence_number;
04047 sequence_number = 0;
04048
04049 if (total_buffer_size <= data_size) {
04050 if (buffer_size < total_buffer_size) {
04051 memcpy(buffer, udp_header + 1, buffer_size);
04052 return buffer_size;
04053 } else {
04054 memcpy(buffer, udp_header + 1, total_buffer_size);
04055 return total_buffer_size;
04056 }
04057 }
04058
04059
04060 n_received = data_size;
04061
04062 if (buffer_size < data_size) {
04063 memcpy(buffer, udp_header + 1, buffer_size);
04064 return buffer_size;
04065 }
04066
04067 memcpy(buffer, udp_header + 1, data_size);
04068
04069
04070 do {
04071
04072 FD_ZERO(&readfds);
04073 FD_SET(sock, &readfds);
04074
04075 timeout.tv_sec = 0;
04076 timeout.tv_usec = 100000;
04077
04078 do {
04079 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
04080 } while (status == -1);
04081
04082
04083
04084
04085
04086 if (!FD_ISSET(sock, &readfds))
04087 return 0;
04088
04089 #ifdef OS_UNIX
04090 do {
04091 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04092
04093
04094 } while (i == -1 && errno == EINTR);
04095 #else
04096 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04097 #endif
04098
04099 sequence_number++;
04100
04101
04102 if (udp_header->serial_number != serial_number ||
04103 udp_header->sequence_number != sequence_number)
04104
04105 goto start;
04106
04107
04108 memcpy(buffer + n_received, udp_header + 1, i - sizeof(UDP_HEADER));
04109
04110 n_received += (i - sizeof(UDP_HEADER));
04111
04112 } while (n_received < total_buffer_size);
04113
04114 return n_received;
04115 }
04116
04117
04118
04119 #ifdef OS_MSDOS
04120 #ifdef sopen
04121
04122
04123
04124
04125
04126
04127 #undef sopen
04128
04129 int sopen(const char *path, int access, int shflag, int mode)
04130 {
04131 return open(path, (access) | (shflag), mode);
04132 }
04133
04134 #endif
04135 #endif
04136
04137
04138
04139
04140
04141
04142
04143
04144
04145 INT ss_tape_open(char *path, INT oflag, INT * channel)
04146
04147
04148
04149
04150
04151
04152
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165
04166
04167 {
04168 #ifdef OS_UNIX
04169 struct mtop arg;
04170
04171 cm_enable_watchdog(FALSE);
04172
04173 *channel = open(path, oflag, 0644);
04174
04175 cm_enable_watchdog(TRUE);
04176
04177 if (*channel < 0)
04178 cm_msg(MERROR, "ss_tape_open", strerror(errno));
04179
04180 if (*channel < 0) {
04181 if (errno == EIO)
04182 return SS_NO_TAPE;
04183 if (errno == EBUSY)
04184 return SS_DEV_BUSY;
04185 return errno;
04186 }
04187 #ifdef MTSETBLK
04188
04189 arg.mt_op = MTSETBLK;
04190 arg.mt_count = 0;
04191
04192 ioctl(*channel, MTIOCTOP, &arg);
04193 #endif
04194
04195 #endif
04196
04197 #ifdef OS_WINNT
04198 INT status;
04199 TAPE_GET_MEDIA_PARAMETERS m;
04200
04201 *channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
04202 0, OPEN_EXISTING, 0, NULL);
04203
04204 if (*channel == (INT) INVALID_HANDLE_VALUE) {
04205 status = GetLastError();
04206 if (status == ERROR_SHARING_VIOLATION) {
04207 cm_msg(MERROR, "ss_tape_open", "tape is used by other process");
04208 return SS_DEV_BUSY;
04209 }
04210 if (status == ERROR_FILE_NOT_FOUND) {
04211 cm_msg(MERROR, "ss_tape_open", "tape device \"%s\" doesn't exist", path);
04212 return SS_NO_TAPE;
04213 }
04214
04215 cm_msg(MERROR, "ss_tape_open", "unknown error %d", status);
04216 return status;
04217 }
04218
04219 status = GetTapeStatus((HANDLE) (*channel));
04220 if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
04221 cm_msg(MERROR, "ss_tape_open", "no media in drive");
04222 return SS_NO_TAPE;
04223 }
04224
04225
04226 memset(&m, 0, sizeof(m));
04227 m.BlockSize = TAPE_BUFFER_SIZE;
04228 SetTapeParameters((HANDLE) (*channel), SET_TAPE_MEDIA_INFORMATION, &m);
04229
04230 #endif
04231
04232 return SS_SUCCESS;
04233 }
04234
04235
04236 INT ss_tape_close(INT channel)
04237
04238
04239
04240
04241
04242
04243
04244
04245
04246
04247
04248
04249
04250
04251
04252
04253
04254 {
04255 INT status;
04256
04257 #ifdef OS_UNIX
04258
04259 status = close(channel);
04260
04261 if (status < 0) {
04262 cm_msg(MERROR, "ss_tape_close", strerror(errno));
04263 return errno;
04264 }
04265 #endif
04266
04267 #ifdef OS_WINNT
04268
04269 if (!CloseHandle((HANDLE) channel)) {
04270 status = GetLastError();
04271 cm_msg(MERROR, "ss_tape_close", "unknown error %d", status);
04272 return status;
04273 }
04274 #endif
04275
04276 return SS_SUCCESS;
04277 }
04278
04279
04280 INT ss_tape_status(char *path)
04281
04282
04283
04284
04285
04286
04287
04288
04289
04290
04291
04292
04293
04294
04295
04296
04297 {
04298 #ifdef OS_UNIX
04299 char str[256];
04300
04301 sprintf(str, "mt -f %s status", path);
04302 system(str);
04303 #endif
04304
04305 #ifdef OS_WINNT
04306 INT status, channel;
04307 DWORD size;
04308 TAPE_GET_MEDIA_PARAMETERS m;
04309 TAPE_GET_DRIVE_PARAMETERS d;
04310 double x;
04311
04312 channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
04313 0, OPEN_EXISTING, 0, NULL);
04314
04315 if (channel == (INT) INVALID_HANDLE_VALUE) {
04316 status = GetLastError();
04317 if (status == ERROR_SHARING_VIOLATION) {
04318 cm_msg(MINFO, "ss_tape_status", "tape is used by other process");
04319 return SS_SUCCESS;
04320 }
04321 if (status == ERROR_FILE_NOT_FOUND) {
04322 cm_msg(MINFO, "ss_tape_status", "tape device \"%s\" doesn't exist", path);
04323 return SS_SUCCESS;
04324 }
04325
04326 cm_msg(MINFO, "ss_tape_status", "unknown error %d", status);
04327 return status;
04328 }
04329
04330
04331 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04332 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04333
04334 status = GetTapeStatus((HANDLE) channel);
04335 if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
04336 cm_msg(MINFO, "ss_tape_status", "no media in drive");
04337 CloseHandle((HANDLE) channel);
04338 return SS_SUCCESS;
04339 }
04340
04341 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04342 GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION, &size, &m);
04343
04344 printf("Hardware error correction is %s\n", d.ECC ? "on" : "off");
04345 printf("Hardware compression is %s\n", d.Compression ? "on" : "off");
04346 printf("Tape %s write protected\n", m.WriteProtected ? "is" : "is not");
04347
04348 if (d.FeaturesLow & TAPE_DRIVE_TAPE_REMAINING) {
04349 x = ((double) m.Remaining.LowPart + (double) m.Remaining.HighPart * 4.294967295E9)
04350 / 1024.0 / 1000.0;
04351 printf("Tape capacity remaining is %d MB\n", (int) x);
04352 } else
04353 printf("Tape capacity is not reported by tape\n");
04354
04355 CloseHandle((HANDLE) channel);
04356
04357 #endif
04358
04359 return SS_SUCCESS;
04360 }
04361
04362
04363 INT ss_tape_write(INT channel, void *pdata, INT count)
04364
04365
04366
04367
04368
04369
04370
04371
04372
04373
04374
04375
04376
04377
04378
04379
04380
04381
04382
04383
04384 {
04385 #ifdef OS_UNIX
04386 INT status;
04387
04388 do {
04389 status = write(channel, pdata, count);
04390
04391
04392
04393
04394 } while (status == -1 && errno == EINTR);
04395
04396 if (status != count) {
04397 cm_msg(MERROR, "ss_tape_write", strerror(errno));
04398
04399 if (errno == EIO)
04400 return SS_IO_ERROR;
04401 else
04402 return SS_TAPE_ERROR;
04403 }
04404 #endif
04405
04406 #ifdef OS_WINNT
04407 INT status;
04408 DWORD written;
04409
04410 WriteFile((HANDLE) channel, pdata, count, &written, NULL);
04411 if (written != (DWORD) count) {
04412 status = GetLastError();
04413 cm_msg(MERROR, "ss_tape_write", "error %d", status);
04414
04415 return SS_IO_ERROR;
04416 }
04417 #endif
04418
04419 return SS_SUCCESS;
04420 }
04421
04422
04423 INT ss_tape_read(INT channel, void *pdata, INT * count)
04424
04425
04426
04427
04428
04429
04430
04431
04432
04433
04434
04435
04436
04437
04438
04439
04440
04441
04442
04443 {
04444 #ifdef OS_UNIX
04445 INT n, status;
04446
04447 do {
04448 n = read(channel, pdata, *count);
04449 } while (n == -1 && errno == EINTR);
04450
04451 if (n == -1) {
04452 if (errno == ENOSPC || errno == EIO)
04453 status = SS_END_OF_TAPE;
04454 else {
04455 if (n == 0 && errno == 0)
04456 status = SS_END_OF_FILE;
04457 else {
04458 cm_msg(MERROR, "ss_tape_read",
04459 "unexpected tape error: n=%d, errno=%d\n", n, errno);
04460 status = errno;
04461 }
04462 }
04463 } else
04464 status = SS_SUCCESS;
04465 *count = n;
04466
04467 return status;
04468
04469 #elif defined(OS_WINNT)
04470
04471 INT status;
04472 DWORD read;
04473
04474 if (!ReadFile((HANDLE) channel, pdata, *count, &read, NULL)) {
04475 status = GetLastError();
04476 if (status == ERROR_NO_DATA_DETECTED)
04477 status = SS_END_OF_TAPE;
04478 else if (status == ERROR_FILEMARK_DETECTED)
04479 status = SS_END_OF_FILE;
04480 else if (status == ERROR_MORE_DATA)
04481 status = SS_SUCCESS;
04482 else
04483 cm_msg(MERROR, "ss_tape_read",
04484 "unexpected tape error: n=%d, errno=%d\n", read, status);
04485 } else
04486 status = SS_SUCCESS;
04487
04488 *count = read;
04489 return status;
04490
04491 #else
04492
04493 return SS_SUCCESS;
04494
04495 #endif
04496 }
04497
04498
04499 INT ss_tape_write_eof(INT channel)
04500
04501
04502
04503
04504
04505
04506
04507
04508
04509
04510
04511
04512
04513
04514
04515
04516
04517 {
04518 INT status;
04519
04520 #ifdef OS_UNIX
04521 struct mtop arg;
04522
04523 arg.mt_op = MTWEOF;
04524 arg.mt_count = 1;
04525
04526 cm_enable_watchdog(FALSE);
04527
04528 status = ioctl(channel, MTIOCTOP, &arg);
04529
04530 cm_enable_watchdog(TRUE);
04531
04532 if (status < 0) {
04533 cm_msg(MERROR, "ss_tape_write_eof", strerror(errno));
04534 return errno;
04535 }
04536 #endif
04537
04538 #ifdef OS_WINNT
04539
04540 TAPE_GET_DRIVE_PARAMETERS d;
04541 DWORD size;
04542
04543 size = sizeof(TAPE_GET_DRIVE_PARAMETERS);
04544 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size, &d);
04545
04546 if (d.FeaturesHigh & TAPE_DRIVE_WRITE_FILEMARKS)
04547 status = WriteTapemark((HANDLE) channel, TAPE_FILEMARKS, 1, FALSE);
04548 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_LONG_FMKS)
04549 status = WriteTapemark((HANDLE) channel, TAPE_LONG_FILEMARKS, 1, FALSE);
04550 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_SHORT_FMKS)
04551 status = WriteTapemark((HANDLE) channel, TAPE_SHORT_FILEMARKS, 1, FALSE);
04552 else
04553 cm_msg(MERROR, "ss_tape_write_eof", "tape doesn't support writing of filemarks");
04554
04555 if (status != NO_ERROR) {
04556 cm_msg(MERROR, "ss_tape_write_eof", "unknown error %d", status);
04557 return status;
04558 }
04559 #endif
04560
04561 return SS_SUCCESS;
04562 }
04563
04564
04565 INT ss_tape_fskip(INT channel, INT count)
04566
04567
04568
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578
04579
04580
04581
04582
04583
04584 {
04585 INT status;
04586
04587 #ifdef OS_UNIX
04588 struct mtop arg;
04589
04590 if (count > 0)
04591 arg.mt_op = MTFSF;
04592 else
04593 arg.mt_op = MTBSF;
04594 arg.mt_count = abs(count);
04595
04596 cm_enable_watchdog(FALSE);
04597
04598 status = ioctl(channel, MTIOCTOP, &arg);
04599
04600 cm_enable_watchdog(TRUE);
04601
04602 if (status < 0) {
04603 cm_msg(MERROR, "ss_tape_fskip", strerror(errno));
04604 return errno;
04605 }
04606 #endif
04607
04608 #ifdef OS_WINNT
04609
04610 status = SetTapePosition((HANDLE) channel, TAPE_SPACE_FILEMARKS, 0,
04611 (DWORD) count, 0, FALSE);
04612
04613 if (status == ERROR_END_OF_MEDIA)
04614 return SS_END_OF_TAPE;
04615
04616 if (status != NO_ERROR) {
04617 cm_msg(MERROR, "ss_tape_fskip", "error %d", status);
04618 return status;
04619 }
04620 #endif
04621
04622 return SS_SUCCESS;
04623 }
04624
04625
04626 INT ss_tape_rskip(INT channel, INT count)
04627
04628
04629
04630
04631
04632
04633
04634
04635
04636
04637
04638
04639
04640
04641
04642
04643
04644
04645 {
04646 INT status;
04647
04648 #ifdef OS_UNIX
04649 struct mtop arg;
04650
04651 if (count > 0)
04652 arg.mt_op = MTFSR;
04653 else
04654 arg.mt_op = MTBSR;
04655 arg.mt_count = abs(count);
04656
04657 cm_enable_watchdog(FALSE);
04658
04659 status = ioctl(channel, MTIOCTOP, &arg);
04660
04661 cm_enable_watchdog(TRUE);
04662
04663 if (status < 0) {
04664 cm_msg(MERROR, "ss_tape_rskip", strerror(errno));
04665 return errno;
04666 }
04667 #endif
04668
04669 #ifdef OS_WINNT
04670
04671 status =
04672 SetTapePosition((HANDLE) channel, TAPE_SPACE_RELATIVE_BLOCKS, 0,
04673 (DWORD) count, 0, FALSE);
04674 if (status != NO_ERROR) {
04675 cm_msg(MERROR, "ss_tape_rskip", "error %d", status);
04676 return status;
04677 }
04678 #endif
04679
04680 return CM_SUCCESS;
04681 }
04682
04683
04684 INT ss_tape_rewind(INT channel)
04685
04686
04687
04688
04689
04690
04691
04692
04693
04694
04695
04696
04697
04698
04699
04700
04701
04702 {
04703 INT status;
04704
04705 #ifdef OS_UNIX
04706 struct mtop arg;
04707
04708 arg.mt_op = MTREW;
04709 arg.mt_count = 0;
04710
04711 cm_enable_watchdog(FALSE);
04712
04713 status = ioctl(channel, MTIOCTOP, &arg);
04714
04715 cm_enable_watchdog(TRUE);
04716
04717 if (status < 0) {
04718 cm_msg(MERROR, "ss_tape_rewind", strerror(errno));
04719 return errno;
04720 }
04721 #endif
04722
04723 #ifdef OS_WINNT
04724
04725 status = SetTapePosition((HANDLE) channel, TAPE_REWIND, 0, 0, 0, FALSE);
04726 if (status != NO_ERROR) {
04727 cm_msg(MERROR, "ss_tape_rewind", "error %d", status);
04728 return status;
04729 }
04730 #endif
04731
04732 return CM_SUCCESS;
04733 }
04734
04735
04736 INT ss_tape_spool(INT channel)
04737
04738
04739
04740
04741
04742
04743
04744
04745
04746
04747
04748
04749
04750
04751
04752
04753
04754 {
04755 INT status;
04756
04757 #ifdef OS_UNIX
04758 struct mtop arg;
04759
04760 #ifdef MTEOM
04761 arg.mt_op = MTEOM;
04762 #else
04763 arg.mt_op = MTSEOD;
04764 #endif
04765 arg.mt_count = 0;
04766
04767 cm_enable_watchdog(FALSE);
04768
04769 status = ioctl(channel, MTIOCTOP, &arg);
04770
04771 cm_enable_watchdog(TRUE);
04772
04773 if (status < 0) {
04774 cm_msg(MERROR, "ss_tape_rewind", strerror(errno));
04775 return errno;
04776 }
04777 #endif
04778
04779 #ifdef OS_WINNT
04780
04781 status = SetTapePosition((HANDLE) channel, TAPE_SPACE_END_OF_DATA, 0, 0, 0, FALSE);
04782 if (status != NO_ERROR) {
04783 cm_msg(MERROR, "ss_tape_spool", "error %d", status);
04784 return status;
04785 }
04786 #endif
04787
04788 return CM_SUCCESS;
04789 }
04790
04791
04792 INT ss_tape_mount(INT channel)
04793
04794
04795
04796
04797
04798
04799
04800
04801
04802
04803
04804
04805
04806
04807
04808
04809
04810 {
04811 INT status;
04812
04813 #ifdef OS_UNIX
04814 struct mtop arg;
04815
04816 #ifdef MTLOAD
04817 arg.mt_op = MTLOAD;
04818 #else
04819 arg.mt_op = MTNOP;
04820 #endif
04821 arg.mt_count = 0;
04822
04823 cm_enable_watchdog(FALSE);
04824
04825 status = ioctl(channel, MTIOCTOP, &arg);
04826
04827 cm_enable_watchdog(TRUE);
04828
04829 if (status < 0) {
04830 cm_msg(MERROR, "ss_tape_mount", strerror(errno));
04831 return errno;
04832 }
04833 #endif
04834
04835 #ifdef OS_WINNT
04836
04837 status = PrepareTape((HANDLE) channel, TAPE_LOAD, FALSE);
04838 if (status != NO_ERROR) {
04839 cm_msg(MERROR, "ss_tape_mount", "error %d", status);
04840 return status;
04841 }
04842 #endif
04843
04844 return CM_SUCCESS;
04845 }
04846
04847
04848 INT ss_tape_unmount(INT channel)
04849
04850
04851
04852
04853
04854
04855
04856
04857
04858
04859
04860
04861
04862
04863
04864
04865
04866 {
04867 INT status;
04868
04869 #ifdef OS_UNIX
04870 struct mtop arg;
04871
04872 #ifdef MTOFFL
04873 arg.mt_op = MTOFFL;
04874 #else
04875 arg.mt_op = MTUNLOAD;
04876 #endif
04877 arg.mt_count = 0;
04878
04879 cm_enable_watchdog(FALSE);
04880
04881 status = ioctl(channel, MTIOCTOP, &arg);
04882
04883 cm_enable_watchdog(TRUE);
04884
04885 if (status < 0) {
04886 cm_msg(MERROR, "ss_tape_unmount", strerror(errno));
04887 return errno;
04888 }
04889 #endif
04890
04891 #ifdef OS_WINNT
04892
04893 status = PrepareTape((HANDLE) channel, TAPE_UNLOAD, FALSE);
04894 if (status != NO_ERROR) {
04895 cm_msg(MERROR, "ss_tape_unmount", "error %d", status);
04896 return status;
04897 }
04898 #endif
04899
04900 return CM_SUCCESS;
04901 }
04902
04903
04904 INT ss_tape_get_blockn(INT channel)
04905
04906
04907
04908
04909
04910
04911
04912
04913 {
04914 #if defined(OS_DARWIN)
04915
04916 return 0;
04917
04918 #elif defined(OS_UNIX)
04919
04920 INT status;
04921 struct mtpos arg;
04922
04923 cm_enable_watchdog(FALSE);
04924 status = ioctl(channel, MTIOCPOS, &arg);
04925 cm_enable_watchdog(TRUE);
04926 if (status < 0) {
04927 if (errno == EIO)
04928 return 0;
04929 else {
04930 cm_msg(MERROR, "ss_tape_get_blockn", strerror(errno));
04931 return -errno;
04932 }
04933 }
04934 return (arg.mt_blkno);
04935
04936 #elif defined(OS_WINNT)
04937
04938 INT status;
04939 TAPE_GET_MEDIA_PARAMETERS media;
04940 unsigned long size;
04941
04942 status =
04943 GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION, &size, &media);
04944 return (media.PartitionCount);
04945
04946 #endif
04947 }
04948
04949
04950
04951
04952
04953
04954
04955
04956
04957
04958 double ss_disk_free(char *path)
04959
04960
04961
04962
04963
04964
04965
04966
04967
04968
04969
04970
04971
04972
04973
04974 {
04975 #ifdef OS_UNIX
04976 #if defined(OS_OSF1)
04977 struct statfs st;
04978 statfs(path, &st, sizeof(st));
04979 return (double) st.f_bavail * st.f_bsize;
04980 #elif defined(OS_LINUX)
04981 struct statfs st;
04982 statfs(path, &st);
04983 return (double) st.f_bavail * st.f_bsize;
04984 #elif defined(OS_SOLARIS)
04985 struct statvfs st;
04986 statvfs(path, &st);
04987 return (double) st.f_bavail * st.f_bsize;
04988 #elif defined(OS_IRIX)
04989 struct statfs st;
04990 statfs(path, &st, sizeof(struct statfs), 0);
04991 return (double) st.f_bfree * st.f_bsize;
04992 #else
04993 struct fs_data st;
04994 statfs(path, &st);
04995 return (double) st.fd_otsize * st.fd_bfree;
04996 #endif
04997
04998 #elif defined(OS_WINNT)
04999 DWORD SectorsPerCluster;
05000 DWORD BytesPerSector;
05001 DWORD NumberOfFreeClusters;
05002 DWORD TotalNumberOfClusters;
05003 char str[80];
05004
05005 strcpy(str, path);
05006 if (strchr(str, ':') != NULL) {
05007 *(strchr(str, ':') + 1) = 0;
05008 strcat(str, DIR_SEPARATOR_STR);
05009 GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector,
05010 &NumberOfFreeClusters, &TotalNumberOfClusters);
05011 } else
05012 GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
05013 &NumberOfFreeClusters, &TotalNumberOfClusters);
05014
05015 return (double) NumberOfFreeClusters *SectorsPerCluster * BytesPerSector;
05016 #else
05017
05018 return 1e9;
05019
05020 #endif
05021 }
05022
05023 #if defined(OS_ULTRIX) || defined(OS_WINNT)
05024 int fnmatch(const char *pat, const char *str, const int flag)
05025 {
05026 while (*str != '\0') {
05027 if (*pat == '*') {
05028 pat++;
05029 if ((str = strchr(str, *pat)) == NULL)
05030 return -1;
05031 }
05032 if (*pat == *str) {
05033 pat++;
05034 str++;
05035 } else
05036 return -1;
05037 }
05038 if (*pat == '\0')
05039 return 0;
05040 else
05041 return -1;
05042 }
05043 #endif
05044
05045 #ifdef OS_WINNT
05046 HANDLE pffile;
05047 LPWIN32_FIND_DATA lpfdata;
05048 #endif
05049 INT ss_file_find(char *path, char *pattern, char **plist)
05050
05051
05052
05053
05054
05055
05056
05057
05058
05059
05060
05061
05062
05063
05064
05065
05066
05067 {
05068 int i;
05069 #ifdef OS_UNIX
05070 DIR *dir_pointer;
05071 struct dirent *dp;
05072
05073 if ((dir_pointer = opendir(path)) == NULL)
05074 return 0;
05075 *plist = (char *) malloc(MAX_STRING_LENGTH);
05076 i = 0;
05077 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
05078 if (fnmatch(pattern, dp->d_name, 0) == 0) {
05079 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
05080 strncpy(*plist + (i * MAX_STRING_LENGTH), dp->d_name, strlen(dp->d_name));
05081 *(*plist + (i * MAX_STRING_LENGTH) + strlen(dp->d_name)) = '\0';
05082 i++;
05083 seekdir(dir_pointer, telldir(dir_pointer));
05084 }
05085 }
05086 closedir(dir_pointer);
05087 #endif
05088 #ifdef OS_WINNT
05089 char str[255];
05090 int first;
05091
05092 strcpy(str, path);
05093 strcat(str, "\\");
05094 strcat(str, pattern);
05095 first = 1;
05096 i = 0;
05097 lpfdata = (WIN32_FIND_DATA *) malloc(sizeof(WIN32_FIND_DATA));
05098 *plist = (char *) malloc(MAX_STRING_LENGTH);
05099 pffile = FindFirstFile(str, lpfdata);
05100 if (pffile == INVALID_HANDLE_VALUE)
05101 return 0;
05102 first = 0;
05103 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
05104 strncpy(*plist + (i * MAX_STRING_LENGTH), lpfdata->cFileName,
05105 strlen(lpfdata->cFileName));
05106 *(*plist + (i * MAX_STRING_LENGTH) + strlen(lpfdata->cFileName)) = '\0';
05107 i++;
05108 while (FindNextFile(pffile, lpfdata)) {
05109 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
05110 strncpy(*plist + (i * MAX_STRING_LENGTH), lpfdata->cFileName,
05111 strlen(lpfdata->cFileName));
05112 *(*plist + (i * MAX_STRING_LENGTH) + strlen(lpfdata->cFileName)) = '\0';
05113 i++;
05114 }
05115 free(lpfdata);
05116 #endif
05117 return i;
05118 }
05119
05120 INT ss_file_remove(char *path)
05121
05122
05123
05124
05125
05126
05127
05128
05129
05130
05131
05132
05133
05134
05135
05136 {
05137 return remove(path);
05138 }
05139
05140 double ss_file_size(char *path)
05141
05142
05143
05144
05145
05146
05147
05148
05149
05150
05151
05152
05153
05154
05155
05156 {
05157 struct stat stat_buf;
05158
05159
05160 stat(path, &stat_buf);
05161 return (double) stat_buf.st_size;
05162 }
05163
05164 double ss_disk_size(char *path)
05165
05166
05167
05168
05169
05170
05171
05172
05173
05174
05175
05176
05177
05178
05179
05180 {
05181 #ifdef OS_UNIX
05182 #if defined(OS_OSF1)
05183 struct statfs st;
05184 statfs(path, &st, sizeof(st));
05185 return (double) st.f_blocks * st.f_fsize;
05186 #elif defined(OS_LINUX)
05187 struct statfs st;
05188 statfs(path, &st);
05189 return (double) st.f_blocks * st.f_bsize;
05190 #elif defined(OS_SOLARIS)
05191 struct statvfs st;
05192 statvfs(path, &st);
05193 if (st.f_frsize > 0)
05194 return (double) st.f_blocks * st.f_frsize;
05195 else
05196 return (double) st.f_blocks * st.f_bsize;
05197 #elif defined(OS_ULTRIX)
05198 struct fs_data st;
05199 statfs(path, &st);
05200 return (double) st.fd_btot * 1024;
05201 #elif defined(OS_IRIX)
05202 struct statfs st;
05203 statfs(path, &st, sizeof(struct statfs), 0);
05204 return (double) st.f_blocks * st.f_bsize;
05205 #else
05206 #error ss_disk_size not defined for this OS
05207 #endif
05208 #endif
05209
05210 #ifdef OS_WINNT
05211 DWORD SectorsPerCluster;
05212 DWORD BytesPerSector;
05213 DWORD NumberOfFreeClusters;
05214 DWORD TotalNumberOfClusters;
05215 char str[80];
05216
05217 strcpy(str, path);
05218 if (strchr(str, ':') != NULL) {
05219 *(strchr(str, ':') + 1) = 0;
05220 strcat(str, DIR_SEPARATOR_STR);
05221 GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector,
05222 &NumberOfFreeClusters, &TotalNumberOfClusters);
05223 } else
05224 GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
05225 &NumberOfFreeClusters, &TotalNumberOfClusters);
05226
05227 return (double) TotalNumberOfClusters *SectorsPerCluster * BytesPerSector;
05228 #endif
05229
05230 return 1e9;
05231 }
05232
05233
05234
05235
05236
05237
05238
05239
05240
05241 void ss_clear_screen()
05242
05243
05244
05245
05246
05247
05248
05249
05250
05251
05252
05253
05254
05255
05256
05257
05258 {
05259 #ifdef OS_WINNT
05260
05261 HANDLE hConsole;
05262 COORD coordScreen = { 0, 0 };
05263 BOOL bSuccess;
05264 DWORD cCharsWritten;
05265 CONSOLE_SCREEN_BUFFER_INFO csbi;
05266 DWORD dwConSize;
05267
05268 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05269
05270
05271 bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
05272 dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
05273
05274
05275 bSuccess = FillConsoleOutputCharacter(hConsole, (TCHAR) ' ',
05276 dwConSize, coordScreen, &cCharsWritten);
05277
05278
05279 bSuccess = SetConsoleCursorPosition(hConsole, coordScreen);
05280 return;
05281
05282 #endif
05283 #if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
05284 printf("\033[2J");
05285 #endif
05286 #ifdef OS_MSDOS
05287 clrscr();
05288 #endif
05289 }
05290
05291
05292 void ss_set_screen_size(int x, int y)
05293
05294
05295
05296
05297
05298
05299
05300
05301
05302
05303
05304
05305
05306
05307
05308
05309 {
05310 #ifdef OS_WINNT
05311
05312 HANDLE hConsole;
05313 COORD coordSize;
05314
05315 coordSize.X = (short) x;
05316 coordSize.Y = (short) y;
05317 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05318 SetConsoleScreenBufferSize(hConsole, coordSize);
05319
05320 #endif
05321 }
05322
05323
05324 void ss_printf(INT x, INT y, const char *format, ...)
05325
05326
05327
05328
05329
05330
05331
05332
05333
05334
05335
05336
05337
05338
05339
05340
05341
05342
05343
05344
05345 {
05346 char str[256];
05347 va_list argptr;
05348
05349 va_start(argptr, format);
05350 vsprintf(str, (char *) format, argptr);
05351 va_end(argptr);
05352
05353 #ifdef OS_WINNT
05354 {
05355 HANDLE hConsole;
05356 COORD dwWriteCoord;
05357 DWORD cCharsWritten;
05358
05359 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05360
05361 dwWriteCoord.X = (short) x;
05362 dwWriteCoord.Y = (short) y;
05363
05364 WriteConsoleOutputCharacter(hConsole, str, strlen(str),
05365 dwWriteCoord, &cCharsWritten);
05366 }
05367
05368 #endif
05369
05370 #if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
05371 printf("\033[%1d;%1d;H", y + 1, x + 1);
05372 printf(str);
05373 fflush(stdout);
05374 #endif
05375
05376 #ifdef OS_MSDOS
05377 gotoxy(x + 1, y + 1);
05378 cputs(str);
05379 #endif
05380 }
05381
05382
05383 char *ss_getpass(char *prompt)
05384
05385
05386
05387
05388
05389
05390
05391
05392
05393
05394
05395
05396
05397
05398
05399
05400 {
05401 static char password[32];
05402
05403 printf(prompt);
05404 memset(password, 0, sizeof(password));
05405
05406 #ifdef OS_UNIX
05407 return (char *) getpass("");
05408 #elif defined(OS_WINNT)
05409 {
05410 HANDLE hConsole;
05411 DWORD nCharsRead;
05412
05413 hConsole = GetStdHandle(STD_INPUT_HANDLE);
05414 SetConsoleMode(hConsole, ENABLE_LINE_INPUT);
05415 ReadConsole(hConsole, password, sizeof(password), &nCharsRead, NULL);
05416 SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT |
05417 ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
05418 printf("\n");
05419
05420 if (password[strlen(password) - 1] == '\r')
05421 password[strlen(password) - 1] = 0;
05422
05423 return password;
05424 }
05425 #elif defined(OS_MSDOS)
05426 {
05427 char c, *ptr;
05428
05429 ptr = password;
05430 while ((c = getchar()) != EOF && c != '\n')
05431 *ptr++ = c;
05432 *ptr = 0;
05433
05434 printf("\n");
05435 return password;
05436 }
05437 #else
05438 {
05439 ss_gets(password, 32);
05440 return password;
05441 }
05442 #endif
05443 }
05444
05445
05446 INT ss_getchar(BOOL reset)
05447
05448
05449
05450
05451
05452
05453
05454
05455
05456
05457
05458
05459
05460
05461
05462
05463
05464
05465
05466 {
05467 #ifdef OS_UNIX
05468
05469 static BOOL init = FALSE;
05470 static struct termios save_termios;
05471 struct termios buf;
05472 int i, fd;
05473 char c[3];
05474
05475 if (_daemon_flag)
05476 return 0;
05477
05478 fd = fileno(stdin);
05479
05480 if (reset) {
05481 if (init)
05482 tcsetattr(fd, TCSAFLUSH, &save_termios);
05483 init = FALSE;
05484 return 0;
05485 }
05486
05487 if (!init) {
05488 tcgetattr(fd, &save_termios);
05489 memcpy(&buf, &save_termios, sizeof(buf));
05490
05491 buf.c_lflag &= ~(ECHO | ICANON | IEXTEN);
05492
05493 buf.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON);
05494
05495 buf.c_cflag &= ~(CSIZE | PARENB);
05496 buf.c_cflag |= CS8;
05497
05498 buf.c_cc[VMIN] = 0;
05499 buf.c_cc[VTIME] = 0;
05500
05501 tcsetattr(fd, TCSAFLUSH, &buf);
05502 init = TRUE;
05503 }
05504
05505 memset(c, 0, 3);
05506 i = read(fd, c, 1);
05507
05508 if (i == 0)
05509 return 0;
05510
05511
05512 if (c[0] == 27) {
05513 i = read(fd, c, 2);
05514 if (i == 0)
05515 return 27;
05516
05517
05518 if (c[1] < 65)
05519 read(fd, c, 1);
05520
05521
05522 switch (c[1]) {
05523 case 49:
05524 return CH_HOME;
05525 case 50:
05526 return CH_INSERT;
05527 case 51:
05528 return CH_DELETE;
05529 case 52:
05530 return CH_END;
05531 case 53:
05532 return CH_PUP;
05533 case 54:
05534 return CH_PDOWN;
05535 case 65:
05536 return CH_UP;
05537 case 66:
05538 return CH_DOWN;
05539 case 67:
05540 return CH_RIGHT;
05541 case 68:
05542 return CH_LEFT;
05543 }
05544 }
05545
05546
05547 if (c[0] == 127)
05548 return CH_BS;
05549
05550 return c[0];
05551
05552 #elif defined(OS_WINNT)
05553
05554 static BOOL init = FALSE;
05555 static INT repeat_count = 0;
05556 static INT repeat_char;
05557 HANDLE hConsole;
05558 DWORD nCharsRead;
05559 INPUT_RECORD ir;
05560 OSVERSIONINFO vi;
05561
05562
05563 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05564 GetVersionEx(&vi);
05565
05566 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT) {
05567
05568 int c;
05569
05570 if (!kbhit())
05571 return 0;
05572
05573 c = getch();
05574 if (c == 224) {
05575 c = getch();
05576 switch (c) {
05577 case 71:
05578 return CH_HOME;
05579 case 72:
05580 return CH_UP;
05581 case 73:
05582 return CH_PUP;
05583 case 75:
05584 return CH_LEFT;
05585 case 77:
05586 return CH_RIGHT;
05587 case 79:
05588 return CH_END;
05589 case 80:
05590 return CH_DOWN;
05591 case 81:
05592 return CH_PDOWN;
05593 case 82:
05594 return CH_INSERT;
05595 case 83:
05596 return CH_DELETE;
05597 }
05598 }
05599 return c;
05600 }
05601
05602 hConsole = GetStdHandle(STD_INPUT_HANDLE);
05603
05604 if (reset) {
05605 SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT |
05606 ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
05607 init = FALSE;
05608 return 0;
05609 }
05610
05611 if (!init) {
05612 SetConsoleMode(hConsole, ENABLE_PROCESSED_INPUT);
05613 init = TRUE;
05614 }
05615
05616 if (repeat_count) {
05617 repeat_count--;
05618 return repeat_char;
05619 }
05620
05621 PeekConsoleInput(hConsole, &ir, 1, &nCharsRead);
05622
05623 if (nCharsRead == 0)
05624 return 0;
05625
05626 ReadConsoleInput(hConsole, &ir, 1, &nCharsRead);
05627
05628 if (ir.EventType != KEY_EVENT)
05629 return ss_getchar(0);
05630
05631 if (!ir.Event.KeyEvent.bKeyDown)
05632 return ss_getchar(0);
05633
05634 if (ir.Event.KeyEvent.wRepeatCount > 1) {
05635 repeat_count = ir.Event.KeyEvent.wRepeatCount - 1;
05636 repeat_char = ir.Event.KeyEvent.uChar.AsciiChar;
05637 return repeat_char;
05638 }
05639
05640 if (ir.Event.KeyEvent.uChar.AsciiChar)
05641 return ir.Event.KeyEvent.uChar.AsciiChar;
05642
05643 if (ir.Event.KeyEvent.dwControlKeyState & (ENHANCED_KEY)) {
05644 switch (ir.Event.KeyEvent.wVirtualKeyCode) {
05645 case 33:
05646 return CH_PUP;
05647 case 34:
05648 return CH_PDOWN;
05649 case 35:
05650 return CH_END;
05651 case 36:
05652 return CH_HOME;
05653 case 37:
05654 return CH_LEFT;
05655 case 38:
05656 return CH_UP;
05657 case 39:
05658 return CH_RIGHT;
05659 case 40:
05660 return CH_DOWN;
05661 case 45:
05662 return CH_INSERT;
05663 case 46:
05664 return CH_DELETE;
05665 }
05666
05667 return ir.Event.KeyEvent.wVirtualKeyCode;
05668 }
05669
05670 return ss_getchar(0);
05671
05672 #elif defined(OS_MSDOS)
05673
05674 int c;
05675
05676 if (!kbhit())
05677 return 0;
05678
05679 c = getch();
05680 if (!c) {
05681 c = getch();
05682 switch (c) {
05683 case 71:
05684 return CH_HOME;
05685 case 72:
05686 return CH_UP;
05687 case 73:
05688 return CH_PUP;
05689 case 75:
05690 return CH_LEFT;
05691 case 77:
05692 return CH_RIGHT;
05693 case 79:
05694 return CH_END;
05695 case 80:
05696 return CH_DOWN;
05697 case 81:
05698 return CH_PDOWN;
05699 case 82:
05700 return CH_INSERT;
05701 case 83:
05702 return CH_DELETE;
05703 }
05704 }
05705 return c;
05706
05707 #else
05708 return -1;
05709 #endif
05710 }
05711
05712
05713 char *ss_gets(char *string, int size)
05714
05715
05716
05717
05718
05719
05720
05721
05722
05723
05724
05725
05726
05727
05728
05729
05730
05731
05732 {
05733 char *p;
05734
05735 do {
05736 p = fgets(string, size, stdin);
05737 } while (p == NULL);
05738
05739
05740 if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
05741 p[strlen(p) - 1] = 0;
05742
05743 return p;
05744 }
05745
05746
05747
05748
05749
05750
05751
05752
05753
05754 INT ss_directio_give_port(INT start, INT end)
05755 {
05756 #ifdef OS_WINNT
05757
05758
05759
05760 OSVERSIONINFO vi;
05761 HANDLE hdio = 0;
05762 DWORD buffer[] = { 6, 0, 0, 0 };
05763 DWORD size;
05764
05765 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05766 GetVersionEx(&vi);
05767
05768
05769 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
05770 hdio =
05771 CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ,
05772 NULL, OPEN_EXISTING, 0, NULL);
05773 if (hdio == INVALID_HANDLE_VALUE) {
05774 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
05775 return -1;
05776 }
05777
05778
05779 buffer[1] = start;
05780 buffer[2] = end;
05781 if (!DeviceIoControl
05782 (hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
05783 return -1;
05784 }
05785
05786 return SS_SUCCESS;
05787 #else
05788 return SS_SUCCESS;
05789 #endif
05790 }
05791
05792
05793 INT ss_directio_lock_port(INT start, INT end)
05794 {
05795 #ifdef OS_WINNT
05796
05797
05798
05799 OSVERSIONINFO vi;
05800 HANDLE hdio;
05801 DWORD buffer[] = { 7, 0, 0, 0 };
05802 DWORD size;
05803
05804 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05805 GetVersionEx(&vi);
05806
05807
05808 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
05809 hdio =
05810 CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ,
05811 NULL, OPEN_EXISTING, 0, NULL);
05812 if (hdio == INVALID_HANDLE_VALUE) {
05813 printf("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
05814 return -1;
05815 }
05816
05817
05818 buffer[1] = start;
05819 buffer[2] = end;
05820 if (!DeviceIoControl
05821 (hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer), NULL, 0, &size, NULL))
05822 return -1;
05823 }
05824
05825 return SS_SUCCESS;
05826 #else
05827 return SS_SUCCESS;
05828 #endif
05829 }
05830
05831
05832
05833
05834
05835
05836
05837
05838
05839 INT ss_syslog(const char *message)
05840
05841
05842
05843
05844
05845
05846
05847
05848
05849
05850
05851
05852
05853
05854
05855
05856 {
05857 #ifdef OS_UNIX
05858 static BOOL init = FALSE;
05859
05860 if (!init) {
05861 #ifdef OS_ULTRIX
05862 openlog("MIDAS", LOG_PID);
05863 #else
05864 openlog("MIDAS", LOG_PID, LOG_USER);
05865 #endif
05866 init = TRUE;
05867 }
05868
05869 syslog(LOG_DEBUG, message);
05870 return SS_SUCCESS;
05871 #elif defined(OS_WINNT)
05872
05873
05874
05875
05876
05877
05878
05879
05880
05881
05882
05883
05884
05885
05886
05887
05888
05889
05890
05891
05892
05893
05894
05895
05896
05897
05898
05899
05900
05901
05902 return SS_SUCCESS;
05903
05904 #else
05905
05906 return SS_SUCCESS;
05907
05908 #endif
05909 }
05910
05911
05912
05913
05914
05915
05916
05917
05918 #define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
05919
05920 char *ss_crypt(char *buf, char *salt)
05921
05922
05923
05924
05925
05926
05927
05928
05929
05930
05931
05932
05933
05934
05935
05936
05937
05938
05939
05940 {
05941 int i, seed;
05942 static char enc_pw[13];
05943
05944 memset(enc_pw, 0, sizeof(enc_pw));
05945 enc_pw[0] = salt[0];
05946 enc_pw[1] = salt[1];
05947
05948 for (i = 0; i < 8 && buf[i]; i++)
05949 enc_pw[i + 2] = buf[i];
05950 for (; i < 8; i++)
05951 enc_pw[i + 2] = 0;
05952
05953 seed = 123;
05954 for (i = 2; i < 13; i++) {
05955 seed = 5 * seed + 27 + enc_pw[i];
05956 enc_pw[i] = (char) bin_to_ascii(seed & 0x3F);
05957 }
05958
05959 return enc_pw;
05960 }
05961
05962
05963
05964
05965
05966
05967
05968
05969 double ss_nan()
05970 {
05971 double nan;
05972
05973 nan = 0;
05974 nan = 0/nan;
05975 return nan;
05976 }
05977 #ifdef OS_WINNT
05978 #include <float.h>
05979 #define isnan(x) _isnan(x)
05980 #elif defined(OS_LINUX)
05981 #include <math.h>
05982 #endif
05983
05984 int ss_isnan(double x)
05985 {
05986 return isnan(x);
05987 }
05988
05989
05990 #endif
05991
05992
05993
05994